dbe_edx.c
来自「db.* (pronounced dee-be star) is an adva」· C语言 代码 · 共 809 行 · 第 1/2 页
C
809 行
return (ERR_READ); dbe_xtrans = DBE_XACTIVE; curr_pos = dbe_chkdba(task->curr_rec, task) ? 0L : phys_addr(task->curr_rec, task); memset(&curr_page, 0, sizeof(DBE_PAGE)); if (dbe_xread(curr_pos, &curr_page, task)) { if (curr_pos) { curr_pos = (F_ADDR) 0; dbe_xread(curr_pos, &curr_page, task); } } return (0);}/* Goto new position in file*/int edx_goto(long n, int mode, DB_TASK *task){ long new_pos; DBE_PAGE new_page; int error; new_pos = (mode == 1) ? curr_pos + n : n; if (new_pos < 0L) return (ERR_FPOS); if ( (curr_page.pg_ptr == NULL) || (new_pos < curr_page.start) || (new_pos > curr_page.end) ) { if ((error = dbe_xread(new_pos, &new_page, task)) != 0) return (error); curr_page = new_page; } curr_pos = new_pos; return (0);}/* Print n lines of hex bytes from file, starting from current position*/int edx_print(long n, DB_TASK *task){ long count, page_count, line_count, pos; int error; char *p; DBE_PAGE page; if (curr_page.pg_ptr == NULL) return (0); error = 0; pos = curr_pos; page = curr_page; p = pos - page.start + page.pg_ptr->buff; /* Calculate number of bytes to print */ count = n * HEX_BYTES; /* Print until correct number of bytes processed */ while (count) { /* Calculate how many bytes to print from this page */ page_count = (count > page.end - pos + 1) ? page.end - pos + 1 : count; /* If end of page, get new page */ if (!page_count) { if ((error = dbe_xread(pos, &page, task)) != 0) break; p = pos - page.start + page.pg_ptr->buff; } else { /* Otherwise print till end of page, or till finished */ while (page_count) { line_count = page_count > HEX_BYTES ? HEX_BYTES : page_count; line_count = do_line(pos, p, line_count, 0); count -= line_count; page_count -= line_count; p += line_count; pos += line_count; } } } /* Flush buffer in case of incomplete line */ do_line(pos, p, 0L, 1); /* Go back to original position */ if (dbe_xread(curr_pos, &curr_page, task)) { curr_pos = 0L; memset(&curr_page, 0, sizeof(DBE_PAGE)); } return (error);}/* Overwrite page contents with string - may affect more than one page NOTE: This function does not write to disk - it updates appropriate cache pages, which may get swapped out to the transaction log file when new pages are read in. The database itself is not updated till hex mode is ended.*/int edx_write(char *cstring, int len, DB_TASK *task){ int i, j, error; long n, count; F_ADDR pos; DBE_PAGE page; char *p; error = 0; count = len; pos = curr_pos; page = curr_page; /* Before starting edit, make sure all affected pages can be accessed, and hold them all in cache till write is complete */ if (count > 0 && pos >= page.start && pos < page.end && page.pg_ptr) page.pg_ptr->holdcnt++; /* hold current page in cache */ for (;;) { /* calculate number of bytes in this page, from current position */ n = page.end - pos + 1; if (n < 0) n = 0; count -= n; pos += n; /* if we're writing less than the number of bytes in page, then we don't need any more pages - otherwise get the next page */ if (count <= 0) break; else if ((error = dbe_xread(pos, &page, task)) == ERR_FPOS) error = ERR_EOF; if (error) return (error); /* keep this page in cache till we've copied the data into it */ page.pg_ptr->holdcnt++; } /* now go back to current position, and start copying data */ count = len; pos = curr_pos; page = curr_page; p = pos - page.start + page.pg_ptr->buff; i = 0; while (count && !error) { /* calculate number of bytes to copy to this page, then copy them */ n = count > page.end - pos + 1 ? page.end - pos + 1 : count; for (j = 0; j < n; j++) p[j] = cstring[i++]; count -= n; pos += n; /* finished with this page - don't care if it gets swapped out */ page.pg_ptr->holdcnt--; /* must call d_trend on exiting hex edit mode - this will write all modified pages to database */ dbe_xtrans = DBE_XMODIFIED; page.pg_ptr->modified = TRUE; /* still some more to do - get next page */ if (count) { error = dbe_xread(pos, &page, task); /* holdcnt should already be set */ p = pos - page.start + page.pg_ptr->buff; } } /* may have swapped out current page - read it back in */ if (dbe_xread(curr_pos, &curr_page, task)) return (ERR_READ); /* Print changed bytes */ edx_print(1L, task); return (0);}/* Search forwards or backwards from current position for string, reading new pages as required*/int edx_search(char *cstring, int len, int mode, DB_TASK *task){ int found, error; F_ADDR pos; DBE_PAGE page; char *p; found = error = 0; pos = curr_pos; page = curr_page; while (!error) { p = pos - page.start + page.pg_ptr->buff; /* Do not release this page during comparison (edx_comp) */ page.pg_ptr->holdcnt++; if (mode > 0) { /* Go through page forwards */ while (!error && pos <= page.end) { if (*p == *cstring) error = edx_comp(&page, pos, &found, cstring, len, task); if (found) break; pos++; p++; } } else { /* Go through page backwards */ while (!error && pos >= page.start) { if (*p == *cstring) error = edx_comp(&page, pos, &found, cstring, len, task); if (found) break; pos--; p--; } } /* Finished with this page - release it */ page.pg_ptr->holdcnt--; if (found || error) break; /* Get next page, if there is one */ if ( (pos < 0L) || ((error = dbe_xread(pos, &page, task)) == ERR_EOF) || (error == ERR_FPOS) ) { error = ERR_SNF; } } if (found) { curr_pos = pos; dbe_xread(curr_pos, &curr_page, task); edx_print(1L, task); } else { if (!error) error = ERR_SNF; if (dbe_xread(curr_pos, &curr_page, task)) { curr_pos = (F_ADDR) 0; memset(&curr_page, 0, sizeof(DBE_PAGE)); } } return (error);}/* Compare contents of page, starting at current position, with string*/int edx_comp( DBE_PAGE *ppage, /* Current page */ long pos, /* Current position in file */ int *flagptr, /* Result of comparison */ char *cstring, /* String to compare */ int len, /* Length of string */ DB_TASK *task){ register int i, j; int error; char *p; DBE_PAGE page, *pp; *flagptr = error = 0; pp = ppage; p = pos - pp->start + pp->pg_ptr->buff; for (i = j = 1; i < len; i++, j++) { /* Reached the end of this page ? */ if (pos + i > ppage->end) { if ((error = dbe_xread(pos + i, pp = &page, task)) != 0) { /* New page */ if (error == ERR_EOF || error == ERR_FPOS) error = 0; break; } p = pos + i - pp->start + pp->pg_ptr->buff; j = 0; } if (cstring[i] != p[j]) break; } if (i == len) *flagptr = 1; return (error);}/* End hex edit - write all updated pages to disk*/int edx_end(DB_TASK *task){ int error = 0; DB_ADDR here; short fno; DB_ULONG rno; DB_TCHAR line[10]; /* If we are now positioned (because of moving) within a record other than the current record, see if the user wishes to make this the current record. */ d_decode_dba(task->curr_rec, &fno, &rno); here = phys_to_dba(fno, curr_pos, task); if ((here > 0) && (here != task->curr_rec)) { dbe_getline(dbe_getstr(M_MOVE), line, sizeof(line) / sizeof(DB_TCHAR)); if ((line[0] == DB_TEXT('y')) || (line[0] == DB_TEXT('Y'))) task->curr_rec = here; } if (dbe_xtrans == DBE_XMODIFIED) { if (d_trend(task) == S_OKAY) error = dbe_xwrite(task); else error = ERR_WRIT; } else if (dbe_xtrans == DBE_XACTIVE) { d_trabort(task); } dbe_xtrans = DBE_XNOTRANS; return (error);}/* Print bytes in hex & ascii, buffering output till complete line is formed. Return number of bytes processed.*/long do_line( long addr, /* Address for start of line */ char *cstring, /* Byte string to print */ long count, /* Number of bytes to print */ int flush) /* Print even if line is incomplete */{#if defined(UNICODE) static wchar_t wbuf[HEX_BYTES + 1];#endif static char cbuf[HEX_BYTES + 1]; static int index = 0; static long address; DB_TCHAR hex_line[50]; int i; if (count + index > HEX_BYTES) count = HEX_BYTES - index; if (index == 0) address = addr; for (i = 0; i < count; i++) cbuf[index++] = cstring[i]; /* If buffer's full, or if flag's set & buffer's not empty, print it */ if ((index == HEX_BYTES) || (flush && (index > 0))) { do_hex(address, cbuf, hex_line, index); for (i = 0; i < index; i++) { if ((((int) cbuf[i] & 0xFF) < ' ') || ((int) cbuf[i] & 0xFF) > 126) { cbuf[i] = '.'; } } cbuf[i] = '\0';#if defined(UNICODE) atow(cbuf, wbuf, HEX_BYTES + 1); wbuf[HEX_BYTES] = 0; disp_str(hex_line, wbuf);#else disp_str(hex_line, cbuf);#endif index = 0; } return (count);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?