sheepy

build system (sheepy) and package manager (spm) for C
git clone https://spartatek.se/git/sheepy.git
Log | Files | Refs | README | LICENSE

LexatomLoader_navigation.i (9019B)


      1 /* -*- C++ -*- vim: set syntax=cpp: */
      2 #ifndef  __QUEX_INCLUDE_GUARD__BUFFER__LEXATOMS__LEXATOM_LOADER_NAVIGATION_I
      3 #define  __QUEX_INCLUDE_GUARD__BUFFER__LEXATOMS__LEXATOM_LOADER_NAVIGATION_I
      4 /* PURPOSE: LexatomLoader's seek: 
      5  *
      6  *        .--------------------------------------------------------------.
      7  *        |  Setting the lexatom index of the next lexatom to be filled  |
      8  *        |                         into the buffer.                     |
      9  *        '--------------------------------------------------------------'
     10  *
     11  * NOT TO CONFUSE with two other forms of seek:
     12  *
     13  *    -- Buffer's seek sets the '_read_p' of the analyzer to a lexatom
     14  *       that is to be treated next.
     15  *    -- QUEX_NAME(ByteLoader)'s seek sets the position in the low level input
     16  *       stream.
     17  * 
     18  * A LexatomLoader's seek has NO direct influence on the content or the pointers
     19  * of the Buffer object that it fills.
     20  *
     21  * The difference between the QUEX_NAME(ByteLoader)'s seeking (stream seeking) and the
     22  * LexatomLoader's seeking is that the QUEX_NAME(ByteLoader )understands the position 
     23  * independently of its meaning. The LexatomLoader already interprets the stream
     24  * as 'lexatoms'. A QUEX_NAME(ByteLoader )sets the stream to a particular byte position.
     25  * A LexatomLoader prepare the input of a lexatom.
     26  *
     27  * (C) Frank-Rene Schaefer                                                   */
     28 
     29 #include "definitions"
     30 #include "bufferBuffer"
     31 #include "MemoryManager"
     32 #include "LexatomLoader"
     33 #include "Buffer_debug"
     34 
     35 QUEX_NAMESPACE_MAIN_OPEN
     36 
     37 QUEX_INLINE QUEX_TYPE_STREAM_POSITION 
     38 QUEX_NAME(LexatomLoader_lexatom_index_tell)(QUEX_NAME(LexatomLoader)* me)
     39 {
     40     return me->lexatom_index_next_to_fill;
     41 }
     42 
     43 
     44 QUEX_INLINE bool 
     45 QUEX_NAME(LexatomLoader_lexatom_index_seek)(QUEX_NAME(LexatomLoader)*         me, 
     46                                              const QUEX_TYPE_STREAM_POSITION  CharacterIndex) 
     47 /* LexatomLoader's seek sets the input position for the next lexatom load in
     48  * the stream. That is, it adapts:
     49  *
     50  *     'lexatom_index_next_to_fill = CharacterIndex' 
     51  *
     52  * and the byte loader is brought into a position so that this will happen.  
     53  *
     54  * RETURNS: true upon success, false else.                                   */
     55 { 
     56     ptrdiff_t                      backup_stomach_byte_n; 
     57     QUEX_TYPE_STREAM_POSITION      backup_byte_loader_position; 
     58     QUEX_TYPE_STREAM_POSITION      backup_lexatom_index_next_to_fill;
     59     QUEX_TYPE_STREAM_POSITION      target_byte_pos;
     60 
     61     if( me->lexatom_index_next_to_fill == CharacterIndex ) return true;
     62 
     63     /* Converter reports '-1' => unable to determine the number of bytes in
     64      *                           the stomach. 
     65      * => When backup position is to setup, start stepping from beginning.
     66      * (This is currently only an issue with ICU; IConv behaves well)        */
     67     backup_stomach_byte_n               = me->stomach_byte_n(me);
     68     backup_byte_loader_position         = me->byte_loader->tell(me->byte_loader);
     69     backup_lexatom_index_next_to_fill = me->lexatom_index_next_to_fill;
     70 
     71     if( me->byte_n_per_lexatom != -1 ) {
     72         /* LINEAR RELATION between lexatom index and stream position       
     73          * (It is not safe to assume that it can be computed)                */
     74         target_byte_pos =   CharacterIndex * me->byte_n_per_lexatom
     75                           + me->byte_loader->initial_position;
     76 
     77         me->byte_loader->seek(me->byte_loader, target_byte_pos);
     78         if( me->byte_loader->tell(me->byte_loader) != target_byte_pos ) {
     79             me->byte_loader->seek(me->byte_loader, backup_byte_loader_position);
     80             return false;
     81         }
     82         me->lexatom_index_next_to_fill = CharacterIndex;
     83         me->stomach_clear(me);
     84         return true;
     85     }
     86 
     87     /* STEPPING (WITHOUT COMPUTING) to the input position.                   */
     88     if( CharacterIndex < me->lexatom_index_next_to_fill ) {
     89         /* Character index lies backward, so stepping needs to start from 
     90          * the initial position.                                             */
     91         QUEX_NAME(LexatomLoader_lexatom_index_reset)(me);
     92     }
     93 
     94     /* step_forward_n_lexatoms() calls derived.load_lexatoms() 
     95      * which increments 'lexatom_index_next_to_fill'.                        */
     96     if( ! QUEX_NAME(LexatomLoader_lexatom_index_step_to)(me, (ptrdiff_t)CharacterIndex) ) {
     97         QUEX_NAME(LexatomLoader_lexatom_index_reset_backup)(me, 
     98                                                             backup_lexatom_index_next_to_fill, 
     99                                                             backup_stomach_byte_n, 
    100                                                             backup_byte_loader_position);
    101         return false;
    102     }
    103     __quex_assert(me->lexatom_index_next_to_fill == CharacterIndex);
    104     return true;
    105 }
    106 
    107 QUEX_INLINE void
    108 QUEX_NAME(LexatomLoader_lexatom_index_reset)(QUEX_NAME(LexatomLoader)* me)
    109 /* Set the lexatom index position to '0' and the byte loader to the initial
    110  * position. The 'stomach' of derived buffer fillers is cleared, so that 
    111  * filling may start from the beginning.                                     */
    112 {
    113     if( me->byte_loader ) {
    114         me->byte_loader->seek(me->byte_loader, me->byte_loader->initial_position);
    115         if( me->byte_loader->tell(me->byte_loader) != me->byte_loader->initial_position ) {
    116             QUEX_ERROR_EXIT("QUEX_NAME(ByteLoader )failed to seek to initial position.\n");
    117         }
    118     }
    119     me->lexatom_index_next_to_fill = 0;
    120     me->stomach_clear(me);
    121 }
    122 
    123 QUEX_INLINE void
    124 QUEX_NAME(LexatomLoader_lexatom_index_reset_backup)(QUEX_NAME(LexatomLoader)* me, 
    125                                                      QUEX_TYPE_STREAM_POSITION Backup_lexatom_index_next_to_fill, 
    126                                                      ptrdiff_t                 BackupStomachByteN, 
    127                                                      QUEX_TYPE_STREAM_POSITION BackupByteLoaderPosition)
    128 /* Reset a previous state of the LexatomLoader and its QUEX_NAME(ByteLoader).            */
    129 {
    130     QUEX_TYPE_STREAM_POSITION backup_byte_pos;
    131 
    132     if( BackupStomachByteN == -1 ) {
    133         /* Since it was not possible to determine the number of bytes in
    134          * the converter's stomach, the backup position must be reached 
    135          * by starting from the begining.                                    */
    136         QUEX_NAME(LexatomLoader_lexatom_index_reset)(me);
    137         if( ! QUEX_NAME(LexatomLoader_lexatom_index_step_to)(me, (ptrdiff_t)Backup_lexatom_index_next_to_fill) ) {
    138             QUEX_ERROR_EXIT("LexatomLoader failed to seek previously reached lexatom.\n");
    139         }
    140         return;
    141     }
    142 
    143     backup_byte_pos = BackupByteLoaderPosition - BackupStomachByteN;
    144     me->byte_loader->seek(me->byte_loader, backup_byte_pos);
    145     me->stomach_clear(me);
    146     me->lexatom_index_next_to_fill = Backup_lexatom_index_next_to_fill;
    147 }
    148 
    149 QUEX_INLINE bool 
    150 QUEX_NAME(LexatomLoader_lexatom_index_step_to)(QUEX_NAME(LexatomLoader)*        me,
    151                                                 const QUEX_TYPE_STREAM_POSITION TargetCI)
    152 /* From the given 'lexatom_index_next_to_fill' (i.e. the return value of 
    153  * 'input_lexatom_tell()') step forward to lexatom index 'TargetCI'. This 
    154  * function is used to reach a target input position in cases where computing 
    155  * is impossible.
    156  *
    157  * THIS FUNCTION DOES NOT BACKUP OR RE-INIT ANYTHING.
    158  * => Must be done upon failure in the caller's function.
    159  *
    160  * RETURNS: true - success; false - else.                                    */
    161 { 
    162     const QUEX_TYPE_STREAM_POSITION ChunkSize = QUEX_SETTING_BUFFER_FILLER_SEEK_TEMP_BUFFER_SIZE;
    163     QUEX_TYPE_LEXATOM               chunk[QUEX_SETTING_BUFFER_FILLER_SEEK_TEMP_BUFFER_SIZE];
    164     QUEX_TYPE_STREAM_POSITION       remaining_n = TargetCI - me->lexatom_index_next_to_fill;
    165     bool                            end_of_stream_f  = false;
    166     bool                            encoding_error_f = false;
    167     size_t                          loaded_n;
    168 
    169     __quex_assert(QUEX_SETTING_BUFFER_FILLER_SEEK_TEMP_BUFFER_SIZE >= 1);
    170 
    171     for(; remaining_n > ChunkSize; remaining_n -= ChunkSize ) {
    172         loaded_n = me->derived.load_lexatoms(me, &chunk[0], (size_t)ChunkSize, 
    173                                              &end_of_stream_f, &encoding_error_f);
    174         me->lexatom_index_next_to_fill += (QUEX_TYPE_STREAM_POSITION)loaded_n;
    175         if( ChunkSize > (QUEX_TYPE_STREAM_POSITION)loaded_n ) {
    176             return false;
    177         }
    178     }
    179     if( remaining_n ) {
    180         loaded_n = me->derived.load_lexatoms(me, &chunk[0], (size_t)remaining_n, 
    181                                              &end_of_stream_f, &encoding_error_f);
    182         me->lexatom_index_next_to_fill += (QUEX_TYPE_STREAM_POSITION)loaded_n;
    183         if( remaining_n > (QUEX_TYPE_STREAM_POSITION)loaded_n ) {
    184             return false;
    185         }
    186     }
    187    
    188     __quex_assert(me->lexatom_index_next_to_fill == TargetCI);
    189     return true;
    190 }
    191 
    192 
    193 QUEX_NAMESPACE_MAIN_CLOSE
    194 
    195 #endif /*   __QUEX_INCLUDE_GUARD__BUFFER__LEXATOMS__LEXATOM_LOADER_NAVIGATION_I */