⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cordxtra.c

📁 Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work
💻 C
📖 第 1 页 / 共 2 页
字号:
{    register chr_data * d = (chr_data *)client_data;    register char * occ = strchr(s, d -> target);        if (occ == 0) {      	d -> pos += strlen(s);      	return(0);    } else {    	d -> pos += occ - s;    	return(1);    }}size_t CORD_chr(CORD x, size_t i, int c){    chr_data d;        d.pos = i;    d.target = c;    if (CORD_iter5(x, i, CORD_chr_proc, CORD_batched_chr_proc, &d)) {        return(d.pos);    } else {    	return(CORD_NOT_FOUND);    }}size_t CORD_rchr(CORD x, size_t i, int c){    chr_data d;        d.pos = i;    d.target = c;    if (CORD_riter4(x, i, CORD_rchr_proc, &d)) {        return(d.pos);    } else {    	return(CORD_NOT_FOUND);    }}/* Find the first occurrence of s in x at position start or later.	*//* This uses an asymptotically poor algorithm, which should typically 	*//* perform acceptably.  We compare the first few characters directly,	*//* and call CORD_ncmp whenever there is a partial match.		*//* This has the advantage that we allocate very little, or not at all.	*//* It's very fast if there are few close misses.			*/size_t CORD_str(CORD x, size_t start, CORD s){    CORD_pos xpos;    size_t xlen = CORD_len(x);    size_t slen;    register size_t start_len;    const char * s_start;    unsigned long s_buf = 0;	/* The first few characters of s	*/    unsigned long x_buf = 0;	/* Start of candidate substring.	*/    				/* Initialized only to make compilers	*/    				/* happy.				*/    unsigned long mask = 0;    register size_t i;    register size_t match_pos;        if (s == CORD_EMPTY) return(start);    if (CORD_IS_STRING(s)) {        s_start = s;        slen = strlen(s);    } else {        s_start = CORD_to_char_star(CORD_substr(s, 0, sizeof(unsigned long)));        slen = CORD_len(s);    }    if (xlen < start || xlen - start < slen) return(CORD_NOT_FOUND);    start_len = slen;    if (start_len > sizeof(unsigned long)) start_len = sizeof(unsigned long);    CORD_set_pos(xpos, x, start);    for (i = 0; i < start_len; i++) {        mask <<= 8;        mask |= 0xff;        s_buf <<= 8;        s_buf |= (unsigned char)s_start[i];        x_buf <<= 8;        x_buf |= (unsigned char)CORD_pos_fetch(xpos);        CORD_next(xpos);    }    for (match_pos = start; ; match_pos++) {    	if ((x_buf & mask) == s_buf) {    	    if (slen == start_len ||    	     	CORD_ncmp(x, match_pos + start_len,    	     	 	  s, start_len, slen - start_len) == 0) {    	        return(match_pos);    	    }    	}	if ( match_pos == xlen - slen ) {	    return(CORD_NOT_FOUND);	}    	x_buf <<= 8;        x_buf |= (unsigned char)CORD_pos_fetch(xpos);        CORD_next(xpos);    }}void CORD_ec_flush_buf(CORD_ec x){    register size_t len = x[0].ec_bufptr - x[0].ec_buf;    char * s;    if (len == 0) return;    s = GC_MALLOC_ATOMIC(len+1);    memcpy(s, x[0].ec_buf, len);    s[len] = '\0';    x[0].ec_cord = CORD_cat_char_star(x[0].ec_cord, s, len);    x[0].ec_bufptr = x[0].ec_buf;}void CORD_ec_append_cord(CORD_ec x, CORD s){    CORD_ec_flush_buf(x);    x[0].ec_cord = CORD_cat(x[0].ec_cord, s);}/*ARGSUSED*/char CORD_nul_func(size_t i, void * client_data){    return((char)(unsigned long)client_data);}CORD CORD_chars(char c, size_t i){    return(CORD_from_fn(CORD_nul_func, (void *)(unsigned long)c, i));}CORD CORD_from_file_eager(FILE * f){    register int c;    CORD_ec ecord;        CORD_ec_init(ecord);    for(;;) {        c = getc(f);        if (c == 0) {          /* Append the right number of NULs	*/          /* Note that any string of NULs is rpresented in 4 words,	*/          /* independent of its length.					*/            register size_t count = 1;                        CORD_ec_flush_buf(ecord);            while ((c = getc(f)) == 0) count++;            ecord[0].ec_cord = CORD_cat(ecord[0].ec_cord, CORD_nul(count));        }        if (c == EOF) break;        CORD_ec_append(ecord, c);    }    (void) fclose(f);    return(CORD_balance(CORD_ec_to_cord(ecord)));}/* The state maintained for a lazily read file consists primarily	*//* of a large direct-mapped cache of previously read values.		*//* We could rely more on stdio buffering.  That would have 2		*//* disadvantages:							*//*  	1) Empirically, not all fseek implementations preserve the	*//*	   buffer whenever they could.					*//*	2) It would fail if 2 different sections of a long cord		*//*	   were being read alternately.					*//* We do use the stdio buffer for read ahead.				*//* To guarantee thread safety in the presence of atomic pointer		*//* writes, cache lines are always replaced, and never modified in	*//* place.								*/# define LOG_CACHE_SZ 14# define CACHE_SZ (1 << LOG_CACHE_SZ)# define LOG_LINE_SZ 9# define LINE_SZ (1 << LOG_LINE_SZ)typedef struct {    size_t tag;    char data[LINE_SZ];    	/* data[i%LINE_SZ] = ith char in file if tag = i/LINE_SZ	*/} cache_line;typedef struct {    FILE * lf_file;    size_t lf_current;	/* Current file pointer value */    cache_line * volatile lf_cache[CACHE_SZ/LINE_SZ];} lf_state;# define MOD_CACHE_SZ(n) ((n) & (CACHE_SZ - 1))# define DIV_CACHE_SZ(n) ((n) >> LOG_CACHE_SZ)# define MOD_LINE_SZ(n) ((n) & (LINE_SZ - 1))# define DIV_LINE_SZ(n) ((n) >> LOG_LINE_SZ)# define LINE_START(n) ((n) & ~(LINE_SZ - 1))typedef struct {    lf_state * state;    size_t file_pos;	/* Position of needed character. */    cache_line * new_cache;} refill_data;/* Executed with allocation lock. */static char refill_cache(client_data)refill_data * client_data;{    register lf_state * state = client_data -> state;    register size_t file_pos = client_data -> file_pos;    FILE *f = state -> lf_file;    size_t line_start = LINE_START(file_pos);    size_t line_no = DIV_LINE_SZ(MOD_CACHE_SZ(file_pos));    cache_line * new_cache = client_data -> new_cache;        if (line_start != state -> lf_current        && fseek(f, line_start, SEEK_SET) != 0) {    	    ABORT("fseek failed");    }    if (fread(new_cache -> data, sizeof(char), LINE_SZ, f)    	<= file_pos - line_start) {    	ABORT("fread failed");    }    new_cache -> tag = DIV_LINE_SZ(file_pos);    /* Store barrier goes here. */    ATOMIC_WRITE(state -> lf_cache[line_no], new_cache);    state -> lf_current = line_start + LINE_SZ;    return(new_cache->data[MOD_LINE_SZ(file_pos)]);}char CORD_lf_func(size_t i, void * client_data){    register lf_state * state = (lf_state *)client_data;    register cache_line * volatile * cl_addr =		&(state -> lf_cache[DIV_LINE_SZ(MOD_CACHE_SZ(i))]);    register cache_line * cl = (cache_line *)ATOMIC_READ(cl_addr);        if (cl == 0 || cl -> tag != DIV_LINE_SZ(i)) {    	/* Cache miss */    	refill_data rd;    	        rd.state = state;        rd.file_pos =  i;        rd.new_cache = GC_NEW_ATOMIC(cache_line);        if (rd.new_cache == 0) OUT_OF_MEMORY;        return((char)(GC_word)        	  GC_call_with_alloc_lock((GC_fn_type) refill_cache, &rd));    }    return(cl -> data[MOD_LINE_SZ(i)]);}    /*ARGSUSED*/void CORD_lf_close_proc(void * obj, void * client_data)  {    if (fclose(((lf_state *)obj) -> lf_file) != 0) {    	ABORT("CORD_lf_close_proc: fclose failed");    }}			CORD CORD_from_file_lazy_inner(FILE * f, size_t len){    register lf_state * state = GC_NEW(lf_state);    register int i;        if (state == 0) OUT_OF_MEMORY;    if (len != 0) {	/* Dummy read to force buffer allocation.  	*/	/* This greatly increases the probability	*/	/* of avoiding deadlock if buffer allocation	*/	/* is redirected to GC_malloc and the		*/	/* world is multithreaded.			*/	char buf[1];	(void) fread(buf, 1, 1, f); 	rewind(f);    }    state -> lf_file = f;    for (i = 0; i < CACHE_SZ/LINE_SZ; i++) {        state -> lf_cache[i] = 0;    }    state -> lf_current = 0;    GC_REGISTER_FINALIZER(state, CORD_lf_close_proc, 0, 0, 0);    return(CORD_from_fn(CORD_lf_func, state, len));}CORD CORD_from_file_lazy(FILE * f){    register long len;        if (fseek(f, 0l, SEEK_END) != 0) {        ABORT("Bad fd argument - fseek failed");    }    if ((len = ftell(f)) < 0) {        ABORT("Bad fd argument - ftell failed");    }    rewind(f);    return(CORD_from_file_lazy_inner(f, (size_t)len));}# define LAZY_THRESHOLD (128*1024 + 1)CORD CORD_from_file(FILE * f){    register long len;        if (fseek(f, 0l, SEEK_END) != 0) {        ABORT("Bad fd argument - fseek failed");    }    if ((len = ftell(f)) < 0) {        ABORT("Bad fd argument - ftell failed");    }    rewind(f);    if (len < LAZY_THRESHOLD) {        return(CORD_from_file_eager(f));    } else {        return(CORD_from_file_lazy_inner(f, (size_t)len));    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -