diff --git a/xorriso/aux_objects.c b/xorriso/aux_objects.c index e125c238..bd598d24 100644 --- a/xorriso/aux_objects.c +++ b/xorriso/aux_objects.c @@ -20,6 +20,8 @@ - LinkiteM, PermiteM which temporarily record relations and states. + - NumbermappeR which maps off_t numbers to other off_t numbers. + */ #ifdef HAVE_CONFIG_H @@ -1082,3 +1084,330 @@ int Permstack_peek(struct PermiteM **o, struct PermiteM *stopper, /* ---------------------------- End PermstacK ----------------------------- */ + +/* ----------------------------- NumbermappeR ----------------------------- */ + +struct NumbermappinG { + off_t from_low; + off_t from_high; + off_t to_low; + off_t to_high; + + struct NumbermappinG *next; +}; + + +off_t Numbermapping__curb(off_t num, off_t min, off_t max, int flag) +{ + if(num < min) + return(min); + if(num > max) + return(max); + return(num); +} + + +int Numbermapping_new(struct NumbermappinG **o, + off_t from_low, off_t from_high, + off_t to_low, off_t to_high, + struct NumbermappinG *next, + off_t min, off_t max, int flag) +{ + struct NumbermappinG *m; + + m= TSOB_FELD(struct NumbermappinG, 1); + if(m == NULL) + return(-1); + m->from_low= Numbermapping__curb(from_low, min, max, 0); + m->from_high= Numbermapping__curb(from_high, min, max, 0); + m->to_low= Numbermapping__curb(to_low, min, max, 0); + m->to_high= Numbermapping__curb(to_high, min, max, 0); + m->next= next; + *o= m; + return(1); +} + + +int Numbermapping_destroy(struct NumbermappinG **o, int flag) +{ + if(*o == NULL) + return(2); + free(*o); + *o= NULL; + return(1); +} + + +int Numbermapping_destroy_all(struct NumbermappinG **o, int flag) +{ + struct NumbermappinG *m, *m_next; + + if(*o == NULL) + return(2); + for(m= *o; m != NULL; m= m_next) { + m_next= m->next; + Numbermapping_destroy(&m, 0); + } + *o= NULL; + return(1); +} + + +/* @return 0=no match, 1=good mapping, 2=curbed mapping +*/ +int Numbermapping_map(struct NumbermappinG *o, off_t from, off_t *to, + off_t min, off_t max, int flag) +{ + struct NumbermappinG *m; + off_t diff; + + if(from < min) + from= min; + else if(from > max) + from= max; + + for(m= o; m != NULL; m= m->next) { + if(from > m->from_high || from < m->from_low) + continue; + diff= from - m->from_low; + if(m->to_low + diff > m->to_high) { + *to= m->to_high; + return(2); + } else { + *to= m->to_low + diff; + return(1); + } + } + *to= from; + return(0); +} + + +struct NumbermappeR { + off_t min; /* lowest permissible number : - 2 exp 60 to + 2 exp 60 - 1 */ + off_t max; /* highest permissible number : - 2 exp 60 to + 2 exp 60 - 1 */ + + int count; /* count of interval mappings */ + struct NumbermappinG *mappings; +}; + + +int Numbermapper_new(struct NumbermappeR **o, off_t min, off_t max, int flag) +{ + struct NumbermappeR *m; + + if(min < -(((off_t) 1) << 60) || min >= (((off_t) 1) << 60) || + max < -(((off_t) 1) << 60) || max >= (((off_t) 1) << 60)) + return(0); + if(min > max) + return(0); + m= TSOB_FELD(struct NumbermappeR, 1); + if(m == NULL) + return(-1); + m->min= min; + m->max= max; + m->count= 0; + m->mappings= NULL; + *o= m; + return(1); +} + + +int Numbermapper_destroy(struct NumbermappeR **o, int flag) +{ + if(*o == NULL) + return(2); + Numbermapping_destroy_all(&((*o)->mappings), 0); + free(*o); + *o= NULL; + return(1); +} + + +int Numbermapper_add(struct NumbermappeR *o, off_t from_low, off_t from_high, + off_t to_low, off_t to_high, int flag) +{ + int ret; + struct NumbermappinG *nm; + + ret= Numbermapping_new(&nm, from_low, from_high, to_low, to_high, + o->mappings, o->min, o->max, 0); + if(ret <= 0) + return(ret); + o->count++; + o->mappings= nm; + return(1); +} + + +int Numbermapper_map(struct NumbermappeR *o, off_t from, off_t *to, int flag) +{ + int ret; + + if(o == NULL) { + *to= from; + return(2); + } + ret= Numbermapping_map(o->mappings, from, to, o->min, o->max, 0); + if(ret <= 0) + return(ret); + return(1); +} + + +/* + @param errmsg character array of at least size 80 + @param flag bit0= accept end-of-text as separator +*/ +int Numbermapper_decode_one(struct NumbermappeR *o, char *cpt, char separator, + off_t *num, char **separator_pos, + char *errmsg, int flag) +{ + int ret; + char *npt, num_text[32]; + + npt= strchr(cpt, separator); + if(npt == NULL) { + if(flag & 1) { + npt= cpt + strlen(cpt); + } else { + sprintf(errmsg, "Expected separator '%c'", separator); + return(0); + } + } + *separator_pos= npt; + if(npt - cpt >= 32) { + sprintf(errmsg, "Number text is too long"); + return(0); + } + strncpy(num_text, cpt, npt - cpt); + num_text[npt - cpt]= 0; + ret= Sfile_text_to_off_t(num_text, num, 0); + if(ret <= 0) { + sprintf(errmsg, "Number text cannot be converted to a number: %s", + num_text); + return(0); + } + if(*num < o->min) { + sprintf(errmsg, "Number %s is too small", num_text); + return(0); + } + if(*num > o->max) { + sprintf(errmsg, "Number %s is too large", num_text); + return(0); + } + return(1); +} + + +/* Decode from_low","from_high"="to_low"[","[to_high]] + @param errmsg character array of at least size 80 +*/ +int Numbermapper_decode(struct NumbermappeR *o, char *text, + off_t *from_low, off_t *from_high, + off_t *to_low, off_t *to_high, + char *errmsg, int flag) +{ + int ret; + char *cpt, *npt; + + *from_low= *to_low= (((off_t) 1) << 61); + *from_high= *to_high= -(((off_t) 1) << 61); + errmsg[0]= 0; + cpt= text; + + ret= Numbermapper_decode_one(o, cpt, ',', from_low, &npt, errmsg, 0); + if(ret <= 0) + return(ret); + cpt= npt + 1; + ret= Numbermapper_decode_one(o, cpt, '=', from_high, &npt, errmsg, 0); + if(ret <= 0) + return(ret); + cpt= npt + 1; + ret= Numbermapper_decode_one(o, cpt, ',', to_low, &npt, errmsg, 1); + if(ret <= 0) + return(ret); + if(*npt == 0) { + *to_high= *to_low; + } else { + cpt= npt + 1; + ret= Numbermapper_decode_one(o, cpt, ':', to_high, &npt, errmsg, 1); + if(ret <= 0) { + if(npt <= cpt + 1) { + *to_high= o->max; + errmsg[0]= 0; + } else { + return(0); + } + } + } + return(1); +} + + +/* @param text character array of at least size 4 * 32 + 4 = 132 +*/ +int Numbermapper_encode(struct NumbermappeR *o, int idx, char *text, int size, + int flag) +{ + int i, ret; + char num_text[80]; + struct NumbermappinG *nm; + + text[0]= 0; + if(idx < 0 || idx >= o->count) + return(0); + nm= o->mappings; + if(nm == NULL) + return(0); + for(i= 0; i < idx; i++) { + nm= nm->next; + if(nm == 0) + return(0); + } + ret= Sfile_off_t_text(num_text, nm->from_low, 0); + if(ret <= 0) + return(0); + if(strlen(text) + strlen(num_text) + 1 >= (size_t) size) + return(0); + strcat(text, num_text); + strcat(text, ","); + ret= Sfile_off_t_text(num_text, nm->from_high, 0); + if(ret <= 0) + return(0); + if(strlen(text) + strlen(num_text) + 1 >= (size_t) size) + return(0); + strcat(text, num_text); + strcat(text, "="); + ret= Sfile_off_t_text(num_text, nm->to_low, 0); + if(ret <= 0) + return(0); + if(strlen(text) + strlen(num_text) + 1 >= (size_t) size) + return(0); + strcat(text, num_text); + if(nm->to_low == nm->to_high) + return(1); + strcat(text, ","); + if(nm->to_high == o->max) + return(1); + ret= Sfile_off_t_text(num_text, nm->to_high, 0); + if(ret <= 0) + return(0); + if(strlen(text) + strlen(num_text) + 1 >= (size_t) size) + return(0); + strcat(text, num_text); + return(1); +} + + +int Numbermapper_get_count(struct NumbermappeR *o, int flag) +{ + if(o == NULL) + return(0); + return(o->count); +} + + + +/* --------------------------- End NumbermappeR --------------------------- */ + diff --git a/xorriso/aux_objects.h b/xorriso/aux_objects.h index 16f6d5ae..103bf283 100644 --- a/xorriso/aux_objects.h +++ b/xorriso/aux_objects.h @@ -191,5 +191,27 @@ int Permstack_peek(struct PermiteM **o, struct PermiteM *stopper, char *disk_path, struct stat **stbuf, int *chattr_flags, int flag); + +struct NumbermappeR; /* interval driven number conversion up to 2 exp 60 */ + +int Numbermapper_new(struct NumbermappeR **o, off_t min, off_t max, int flag); + +int Numbermapper_destroy(struct NumbermappeR **o, int flag); + +int Numbermapper_add(struct NumbermappeR *o, off_t from_low, off_t from_high, + off_t to_low, off_t to_high, int flag); + +int Numbermapper_map(struct NumbermappeR *o, off_t from, off_t *to, int flag); + +int Numbermapper_decode(struct NumbermappeR *o, char *text, + off_t *from_low, off_t *from_high, + off_t *to_low, off_t *to_high, + char *errmsg, int flag); + +int Numbermapper_get_count(struct NumbermappeR *o, int flag); + +int Numbermapper_encode(struct NumbermappeR *o, int idx, char *text, int size, + int flag); + #endif /* ! Xorriso_pvt_auxobj_includeD */ diff --git a/xorriso/xorriso_timestamp.h b/xorriso/xorriso_timestamp.h index df198fec..2b0e2903 100644 --- a/xorriso/xorriso_timestamp.h +++ b/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2025.03.01.150925" +#define Xorriso_timestamP "2025.03.27.204229"