/*! \brief Obtention depuis le fichier du bloc contenant l'enregistrement * d'indice-fichier donné. * * \ingroup cache_internal * * Cette fonction retourne un bloc valide contenant l'enregistrement cherché. * On cherche d'abord l'enregistrement dans le cache grâce à Find_Block. Si on * ne l'y trouve pas, on obtient un bloc libre grâce à la fonction * Strategy_Replace_Block (qui, comme son nom l'indique, depend de la * strategie). On sauve ce bloc si il est marqué modifié puis on initialise son * entête et on lit son contenu depuis le fichier (Read_Block). * * \param pcache un pointeur sur le cache à synchroniser * \param irfile indice du bloc cherché dans le fichier * \return un pointeur sur l'entête du bloc (ou le pointeur nul si le bloc n'est pas trouvé) */ struct Cache_Block_Header *Get_Block(struct Cache *pcache, int irfile) { struct Cache_Block_Header *pbh; if ((pbh = Find_Block(pcache, irfile)) == NULL) { /* L'enregistrement n'est pas dans le cache */ /* On demande un block à Strategy_Replace_Block */ pbh = Strategy_Replace_Block(pcache); if (pbh == NULL) return NULL; /* Si le bloc libéré est valide et modifié, on le sauve sur le fichier */ if ((pbh->flags & VALID) && (pbh->flags & MODIF) && (Write_Block(pcache, pbh) != CACHE_OK)) return NULL; /* On remplit le bloc libre et son entête avec l'information de * l'enregistrement d'indice-fichier irfile */ pbh->flags = 0; pbh->ibfile = irfile / pcache->nrecords; /* indice du bloc dans le fichier */ if (Read_Block(pcache, pbh) != CACHE_OK) return NULL; } /* Soit l'enregistrement était déjà dans le cache, soit on vient de l'y mettre */ return pbh; }
*/ static REBCNT Parse_To(REBPARSE *parse, REBCNT index, REBVAL *item, REBFLG is_thru) /* ** Parse TO a specific: ** 1. integer - index position ** 2. END - end of input ** 3. value - according to datatype ** 4. block of values - the first one we hit ** ***********************************************************************/ { REBSER *series = parse->series; REBCNT i; REBSER *ser; // TO a specific index position. if (IS_INTEGER(item)) { i = (REBCNT)Int32(item) - (is_thru ? 0 : 1); if (i > series->tail) i = series->tail; } // END else if (IS_WORD(item) && VAL_WORD_CANON(item) == SYM_END) { i = series->tail; } else if (IS_BLOCK(item)) { i = To_Thru(parse, index, item, is_thru); } else { if (IS_BLOCK_INPUT(parse)) { REBVAL word; /// !!!Temp, but where can we put it? if (IS_LIT_WORD(item)) { // patch to search for word, not lit. word = *item; VAL_SET(&word, REB_WORD); item = &word; } ///i = Find_Value(series, index, tail-index, item, 1, (REBOOL)(PF_CASE & flags), FALSE, 1); i = Find_Block(series, index, series->tail, item, 1, HAS_CASE(parse)?AM_FIND_CASE:0, 1); if (i != NOT_FOUND && is_thru) i++; } else { // "str" if (ANY_BINSTR(item)) { if (!IS_STRING(item) && !IS_BINARY(item)) { // !!! Can this be optimized not to use COPY? ser = Copy_Form_Value(item, 0); i = Find_Str_Str(series, 0, index, series->tail, 1, ser, 0, ser->tail, HAS_CASE(parse)); if (i != NOT_FOUND && is_thru) i += ser->tail; } else { i = Find_Str_Str(series, 0, index, series->tail, 1, VAL_SERIES(item), VAL_INDEX(item), VAL_LEN(item), HAS_CASE(parse)); if (i != NOT_FOUND && is_thru) i += VAL_LEN(item); } } // #"A" else if (IS_CHAR(item)) { i = Find_Str_Char(series, 0, index, series->tail, 1, VAL_CHAR(item), HAS_CASE(parse)); if (i != NOT_FOUND && is_thru) i++; } } } return i; }