/* XXX: change API to go faster */ int eb_nextc(EditBuffer *b, int offset, int *next_ptr) { u8 buf[MAX_CHAR_BYTES], *p; int ch; if (offset >= b->total_size) { offset = b->total_size; ch = '\n'; } else { eb_read(b, offset, buf, 1); /* we use directly the charset conversion table to go faster */ ch = b->charset_state.table[buf[0]]; offset++; if (ch == ESCAPE_CHAR) { eb_read(b, offset, buf + 1, MAX_CHAR_BYTES - 1); p = buf; ch = b->charset_state.decode_func(&b->charset_state, (const u8 **)&p); offset += (p - buf) - 1; } } if (next_ptr) *next_ptr = offset; return ch; }
static int shell_get_colorized_line(EditState *e, unsigned int *buf, int buf_size, int offset, int line_num) { EditBuffer *b = e->b; ShellState *s = b->priv_data; EditBuffer *b_color = s->b_color; int color, offset1, c; unsigned int *buf_ptr, *buf_end; unsigned char buf1[1]; /* record line */ buf_ptr = buf; buf_end = buf + buf_size; for (;;) { eb_read(b_color, offset, buf1, 1); color = buf1[0]; c = eb_nextc(b, offset, &offset1); if (c == '\n') break; if (buf_ptr < buf_end) { /* XXX: test */ if (color != s->def_color) { c |= (QE_STYLE_TTY | color) << STYLE_SHIFT; } *buf_ptr++ = c; } offset = offset1; } return buf_ptr - buf; }
static int raw_save_buffer(EditBuffer *b, const char *filename) { int fd, len, size; unsigned char buf[IOBUF_SIZE]; fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600); if (fd < 0) return -1; size = b->total_size; while (size > 0) { len = size; if (len > IOBUF_SIZE) len = IOBUF_SIZE; eb_read(b, b->total_size - size, buf, len); len = write(fd, buf, len); if (len < 0) { close(fd); return -1; } size -= len; } close(fd); return 0; }
int eb_get_str(EditBuffer *b, char *buf, int buf_size) { int len; len = b->total_size; if (len > buf_size - 1) len = buf_size - 1; eb_read(b, 0, buf, len); buf[len] = '\0'; return len; }
/* XXX: suppress that */ int eb_prevc(EditBuffer *b, int offset, int *prev_ptr) { int ch; u8 buf[MAX_CHAR_BYTES], *q; if (offset <= 0) { offset = 0; ch = '\n'; } else { /* XXX: it cannot be generic here. Should use the line/column system to be really generic */ offset--; q = buf + sizeof(buf) - 1; eb_read(b, offset, q, 1); if (b->charset == &charset_utf8) { while (*q >= 0x80 && *q < 0xc0) { if (offset == 0 || q == buf) { /* error : take only previous char */ offset += buf - 1 - q; ch = buf[sizeof(buf) - 1]; goto the_end; } offset--; q--; eb_read(b, offset, q, 1); } ch = utf8_decode((const char **)(void *)&q); } else { ch = *q; } } the_end: if (prev_ptr) *prev_ptr = offset; return ch; }
void list_toggle_selection(EditState *s) { int offset; unsigned char ch; offset = list_get_offset(s); eb_read(s->b, offset , &ch, 1); if (ch == ' ') ch = '*'; else ch = ' '; eb_write(s->b, offset , &ch, 1); text_move_up_down(s, 1); }
/* go to previous synchronization point */ static int mpeg_backward_offset(EditState *s, int offset) { unsigned char buf[4]; unsigned int startcode; int ret; for (;;) { if (offset <= 0) break; ret = eb_read(s->b, offset, buf, 4); if (ret != 4) break; startcode = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; if ((startcode & 0xffffff00) == 0x00000100) { break; } offset--; } return offset; }
void do_undo(EditState *s) { EditBuffer *b = s->b; int log_index, saved, size_trailer; LogBuffer lb; if (!b->log_buffer) return; if (s->qe_state->last_cmd_func != do_undo) b->log_current = 0; if (b->log_current == 0) { log_index = b->log_new_index; } else { log_index = b->log_current - 1; } if (log_index == 0) { put_status(s, "No futher undo information"); return; } else { put_status(s, "Undo!"); } /* go backward */ log_index -= sizeof(int); eb_read(b->log_buffer, log_index, (unsigned char *)&size_trailer, sizeof(int)); log_index -= size_trailer + sizeof(LogBuffer); /* log_current is 1 + index to have zero as default value */ b->log_current = log_index + 1; /* play the log entry */ eb_read(b->log_buffer, log_index, (unsigned char *)&lb, sizeof(LogBuffer)); log_index += sizeof(LogBuffer); switch (lb.op) { case LOGOP_WRITE: /* we must disable the log because we want to record a single write (we should have the single operation: eb_write_buffer) */ saved = b->save_log; b->save_log = 0; eb_delete(b, lb.offset, lb.size); eb_insert_buffer(b, lb.offset, b->log_buffer, log_index, lb.size); b->save_log = saved; eb_addlog(b, LOGOP_WRITE, lb.offset, lb.size); s->offset = lb.offset + lb.size; break; case LOGOP_DELETE: /* we must also disable the log there because the log buffer would be modified BEFORE we insert it by the implicit eb_addlog */ saved = b->save_log; b->save_log = 0; eb_insert_buffer(b, lb.offset, b->log_buffer, log_index, lb.size); b->save_log = saved; eb_addlog(b, LOGOP_INSERT, lb.offset, lb.size); s->offset = lb.offset + lb.size; break; case LOGOP_INSERT: eb_delete(b, lb.offset, lb.size); s->offset = lb.offset; break; default: abort(); } b->modified = lb.was_modified; }
static void eb_addlog(EditBuffer *b, enum LogOperation op, int offset, int size) { int was_modified, len, size_trailer; LogBuffer lb; EditBufferCallbackList *l; /* call each callback */ for (l = b->first_callback; l != NULL; l = l->next) { l->callback(b, l->opaque, op, offset, size); } was_modified = b->modified; b->modified = 1; if (!b->save_log) return; if (!b->log_buffer) { char buf[256]; snprintf(buf, sizeof(buf), "*log <%s>*", b->name); b->log_buffer = eb_new(buf, BF_SYSTEM); if (!b->log_buffer) return; } /* XXX: better test to limit size */ if (b->nb_logs >= (NB_LOGS_MAX-1)) { /* no free space, delete least recent entry */ eb_read(b->log_buffer, 0, (unsigned char *)&lb, sizeof(LogBuffer)); len = lb.size; if (lb.op == LOGOP_INSERT) len = 0; len += sizeof(LogBuffer) + sizeof(int); eb_delete(b->log_buffer, 0, len); b->log_new_index -= len; if (b->log_current > 1) b->log_current -= len; b->nb_logs--; } /* header */ lb.op = op; lb.offset = offset; lb.size = size; lb.was_modified = was_modified; eb_write(b->log_buffer, b->log_new_index, (unsigned char *) &lb, sizeof(LogBuffer)); b->log_new_index += sizeof(LogBuffer); /* data */ switch (op) { case LOGOP_DELETE: case LOGOP_WRITE: eb_insert_buffer(b->log_buffer, b->log_new_index, b, offset, size); b->log_new_index += size; size_trailer = size; break; default: size_trailer = 0; break; } /* trailer */ eb_write(b->log_buffer, b->log_new_index, (unsigned char *)&size_trailer, sizeof(int)); b->log_new_index += sizeof(int); b->nb_logs++; }
static int hex_display(EditState *s, DisplayState *ds, int offset) { int j, len, ateof; int offset1, offset2; unsigned char b; display_bol(ds); ds->style = QE_STYLE_COMMENT; display_printf(ds, -1, -1, "%08x ", offset); ateof = 0; len = s->b->total_size - offset; if (len > s->disp_width) len = s->disp_width; if (s->mode == &hex_mode) { ds->style = QE_STYLE_FUNCTION; for (j = 0; j < s->disp_width; j++) { display_char(ds, -1, -1, ' '); offset1 = offset + j; offset2 = offset1 + 1; if (j < len) { eb_read(s->b, offset1, &b, 1); display_printhex(ds, offset1, offset2, b, 2); } else { if (!ateof) { ateof = 1; } else { offset1 = offset2 = -1; } ds->cur_hex_mode = s->hex_mode; display_printf(ds, offset1, offset2, " "); ds->cur_hex_mode = 0; } if ((j & 7) == 7) display_char(ds, -1, -1, ' '); } display_char(ds, -1, -1, ' '); } ds->style = 0; display_char(ds, -1, -1, ' '); ateof = 0; for (j = 0; j < s->disp_width; j++) { offset1 = offset + j; offset2 = offset1 + 1; if (j < len) { eb_read(s->b, offset1, &b, 1); } else { b = ' '; if (!ateof) { ateof = 1; } else { offset1 = offset2 = -1; } } display_char(ds, offset1, offset2, to_disp(b)); } display_eol(ds, -1, -1); if (len >= s->disp_width) return offset + len; else return -1; }
void hex_write_char(EditState *s, int key) { unsigned int cur_ch, ch; int hsize, shift, cur_len, len, h; char buf[10]; if (s->hex_mode) { if (s->unihex_mode) hsize = 4; else hsize = 2; h = to_hex(key); if (h < 0) return; if (s->insert && s->hex_nibble == 0) { ch = h << ((hsize - 1) * 4); if (s->unihex_mode) { len = unicode_to_charset(buf, ch, s->b->charset); } else { len = 1; buf[0] = ch; } eb_insert(s->b, s->offset, buf, len); } else { if (s->unihex_mode) { cur_ch = eb_nextc(s->b, s->offset, &cur_len); cur_len -= s->offset; } else { eb_read(s->b, s->offset, buf, 1); cur_ch = buf[0]; cur_len = 1; } shift = (hsize - s->hex_nibble - 1) * 4; ch = (cur_ch & ~(0xf << shift)) | (h << shift); if (s->unihex_mode) { len = unicode_to_charset(buf, ch, s->b->charset); } else { len = 1; buf[0] = ch; } #if 1 eb_replace(s->b, s->offset, cur_len, buf, len); #else if (cur_len == len) { eb_write(s->b, s->offset, buf, len); } else { eb_delete(s->b, s->offset, cur_len); eb_insert(s->b, s->offset, buf, len); } #endif } if (++s->hex_nibble == hsize) { s->hex_nibble = 0; if (s->offset < s->b->total_size) s->offset += len; } } else { text_write_char(s, key); } }
static int mpeg_display(EditState *s, DisplayState *ds, int offset) { unsigned int startcode; int ret, badchars, offset_start; unsigned char buf[4]; /* search start code */ badchars = 0; display_bol(ds); display_printf(ds, -1, -1, "%08x:", offset); for (;;) { ret = eb_read(s->b, offset, buf, 4); if (ret == 0) { if (badchars) display_eol(ds, -1, -1); goto the_end; } if (ret == 4) { startcode = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; if ((startcode & 0xffffff00) == 0x00000100) { if (badchars) { display_eol(ds, -1, -1); display_bol(ds); display_printf(ds, -1, -1, "%08x:", offset); } break; } } /* display unknown chars */ display_printf(ds, -1, -1, " ["); display_printhex(ds, offset, offset + 1, buf[0], 2); display_printf(ds, -1, -1, "]"); offset++; if (++badchars == 8) { badchars = 0; display_eol(ds, -1, -1); goto the_end; } } offset_start = offset; offset += 4; display_printf(ds, offset_start, offset, " [%08x] ", startcode); switch (startcode) { case SEQ_END_CODE: display_printf(ds, -1, -1, "SEQ_END"); break; case SEQ_START_CODE: display_printf(ds, -1, -1, "SEQUENCE"); break; case PICTURE_START_CODE: display_printf(ds, -1, -1, "PICTURE"); break; case GOP_START_CODE: display_printf(ds, -1, -1, "GOP"); break; case EXT_START_CODE: display_printf(ds, -1, -1, "EXT"); break; case PACK_START_CODE: display_printf(ds, -1, -1, "PACK"); break; case SYSTEM_HEADER_START_CODE: display_printf(ds, -1, -1, "SYSTEM"); break; default: if (startcode >= SLICE_MIN_START_CODE && startcode <= SLICE_MAX_START_CODE) { display_printf(ds, -1, -1, "SLICE %d", startcode & 0xff); } else { display_printf(ds, -1, -1, "UNKNOWN", startcode); } break; } display_eol(ds, -1, -1); the_end: return offset; }