Changeset 3563


Ignore:
Timestamp:
Nov 18, 2013, 5:22:30 AM (5 years ago)
Author:
cameron
Message:

Update icxmlc files

Location:
icXML/icXML-devel/src
Files:
48 edited

Legend:

Unmodified
Added
Removed
  • icXML/icXML-devel/src/icxmlc/Array.hpp

    r3103 r3563  
    77/*
    88 * @author Nigel Medforth, nigelm -at- interational-characters.com
    9  * @version $Id: Array.hpp 292 2013-04-13 02:02:18Z nigelm $
     9 * @version $Id: Array.hpp 371 2013-09-05 21:51:18Z nigelm $
    1010 *
    1111 */
     
    2929#if defined(PRINT_ARRAY_DEBUG_MESSAGES) && defined(PRINT_DEBUG_MESSAGE)
    3030#include <typeinfo>
    31 #define DEBUG_ARRAY_MESSAGE(x) DEBUG_MESSAGE(x)
     31#include <cxxabi.h>
     32#define DEBUG_ARRAY_MESSAGE(x) { char * __name = name(); DEBUG_MESSAGE("Array<" << __name << ">::" << x); free(__name); }
    3233#else
    3334#define DEBUG_ARRAY_MESSAGE(x)
     
    4950                static void memzero(T * ptr, size_t count);
    5051
    51         static void memzero(T & ptr, size_t count);
     52        static void memzero(T & ptr, size_t count = 1);
    5253
    5354        static void set(T * ptr, const T value, size_t count);
     
    5657
    5758        static void deallocate(T *ptr);
     59
     60        #if defined(PRINT_ARRAY_DEBUG_MESSAGES) && defined(PRINT_DEBUG_MESSAGE)
     61        static char * name();
     62        #endif
    5863
    5964        protected:
     
    162167                {
    163168            #ifdef PRINT_DEBUG_MESSAGE
    164             if (i >= _capacity)
    165             {
    166                 assert(!"i >= _capacity");
    167             }
     169            assert(i < capacity());
    168170            #endif
    169171            return _array[i];
     
    174176                {
    175177            #ifdef PRINT_DEBUG_MESSAGE
    176             if (i >= _capacity)
    177             {
    178                 assert(!"i >= _capacity");
    179             }
     178            assert(i < capacity());
    180179            #endif
    181                         return _array[i];
     180            return _array[i];
    182181                }
    183182
     
    207206
    208207        IDISA_ALWAYS_INLINE
     208        const_ptr_t first() const { return &_array[0]; }
     209
     210        IDISA_ALWAYS_INLINE
    209211        const_ptr_t limit() const { return &_array[_capacity]; }
     212
     213        #if defined(PRINT_ARRAY_DEBUG_MESSAGES) && defined(PRINT_DEBUG_MESSAGE)
     214        static char * name() { return Array<T>::name(); }
     215        #endif
    210216
    211217        private:
     
    250256DynamicArray<T, baseCapacity, padding>::calculateNewCapacity(const size_t requiredSize) const
    251257{
    252     const size_t additionalCapacity = capacity() - (requiredSize % baseCapacity);
    253     return max(capacity() * 2, requiredSize + additionalCapacity);
     258    //const size_t additionalCapacity = capacity() - (requiredSize % baseCapacity);
     259    //return max(capacity() * 2, requiredSize + additionalCapacity);
     260
     261    return requiredSize;
    254262}
    255263
     
    259267expand(const_ptr_t const input, size_t count)
    260268{
    261     const size_t newCapacity = calculateNewCapacity(count);
     269    const size_t newCapacity = calculateNewCapacity(max<size_t>(count, capacity() * 2));
     270
     271    DEBUG_ARRAY_MESSAGE("expand(" << count << " (" << newCapacity << "))")
     272
     273    ptr_t newArray = Array<T>::allocate(newCapacity + DYNAMIC_ARRAY_PADDING);
     274
     275        if (unlikely(!newArray))
     276    {
     277                assert (!"DYNAMIC ARRAY: MEMORY ALLOCATION ERROR!");
     278                throw;
     279        }
     280
     281        const size_t size = min(count, capacity());
     282
     283        Array<T>::copy(input, newArray, size);
     284        Array<T>::memzero(&newArray[size], newCapacity - size + DYNAMIC_ARRAY_PADDING);
     285
     286        deallocateArrayIfNecessary();
     287
     288        _array = newArray;
     289        _capacity = newCapacity;
     290}
     291
     292/// ---------------------------------------------------------------------------------------------- ///
     293
     294ARRAY_IMPL(void)::
     295resizeToFit(const size_t size)
     296{
     297        resizeToFit(capacity(), size);
     298}
     299
     300
     301ARRAY_IMPL(void)::
     302resizeToFit(const size_t copyUpToIndex, const size_t newSize)
     303{
     304    const size_t newCapacity = calculateNewCapacity(newSize);
     305
     306    DEBUG_ARRAY_MESSAGE("resizeToFit(" << copyUpToIndex << ',' << newSize << " (" << newCapacity << "))")
     307
     308    if (newCapacity <= capacity()) return;
    262309
    263310        ptr_t newArray = Array<T>::allocate(newCapacity + DYNAMIC_ARRAY_PADDING);
     
    269316        }
    270317
    271         const size_t size = min(count, capacity());
    272 
    273         Array<T>::copy(input, newArray, size);
    274         Array<T>::memzero(&newArray[size], newCapacity - size + DYNAMIC_ARRAY_PADDING);
    275 
    276         deallocateArrayIfNecessary();
    277 
    278         _array = newArray;
    279         _capacity = newCapacity;
    280 }
    281 
    282 /// ---------------------------------------------------------------------------------------------- ///
    283 
    284 ARRAY_IMPL(void)::
    285 resizeToFit(const size_t size)
    286 {
    287         resizeToFit(capacity(), size);
    288 }
    289 
    290 
    291 ARRAY_IMPL(void)::
    292 resizeToFit(const size_t copyUpToIndex, const size_t newSize)
    293 {
    294     const size_t newCapacity = calculateNewCapacity(newSize);
    295 
    296         ptr_t newArray = Array<T>::allocate(newCapacity + DYNAMIC_ARRAY_PADDING);
    297 
    298         if (unlikely(!newArray))
    299         {
    300                 assert (!"DYNAMIC ARRAY: MEMORY ALLOCATION ERROR!");
    301                 throw;
    302         }
    303 
    304318    Array<T>::copy(_array, newArray, copyUpToIndex);
    305319    Array<T>::memzero(&newArray[copyUpToIndex], newCapacity - copyUpToIndex + DYNAMIC_ARRAY_PADDING);
     
    372386    if (unlikely(capacity() < (to + count)))
    373387    {
    374         resizeToFit(to, to + count);
     388        resizeToFit(to, max<size_t>(to + count, capacity() * 2));
    375389    }
    376390    Array<T>::copy(from, &_array[to], count);
     
    382396    if (unlikely(capacity() < (to + count)))
    383397    {
    384         resizeToFit(to, to + count);
     398        resizeToFit(to, max<size_t>(to + count, capacity() * 2));
    385399    }
    386400    Array<T>::move(from, &_array[to], count);
     
    392406    if (unlikely(capacity() <= index))
    393407    {
    394         resizeToFit(capacity(), index);
     408        resizeToFit(capacity(), max<size_t>(index, capacity() * 2));
    395409    }
    396410    _array[index] = value;
     
    402416    if (unlikely(capacity() <= (index + count)))
    403417    {
    404         resizeToFit(capacity(), index + count);
     418        resizeToFit(capacity(), max<size_t>(index + count, capacity() * 2));
    405419    }
    406420    Array<T>::set(&_array[index], value, count);
     
    416430                typedef T & ref_t;
    417431                typedef const T & const_ref_t;
     432        typedef T * ptr_t;
     433        typedef const T * const_ptr_t;
    418434
    419435        public:
    420436
     437        typedef T Type;
     438
    421439                FixedArray()
    422440                {
     
    441459
    442460                size_t copy_to_front(const size_t from, const size_t to);
     461
     462        IDISA_ALWAYS_INLINE
     463        const_ptr_t first() const { return &_array[0]; }
     464
     465        IDISA_ALWAYS_INLINE
     466        const_ptr_t limit() const { return &_array[fixedCapacity]; }
    443467
    444468                size_t capacity() const { return fixedCapacity; }
     
    480504void Array<T>::copy(const T * input, T * output, size_t count)
    481505{
    482     DEBUG_ARRAY_MESSAGE("Array<" << typeid(T).name() << ">::copy(" << std::hex << ((ptrdiff_t)input) << ',' << ((ptrdiff_t)output) << std::dec << ',' << count << ')');
     506    DEBUG_ARRAY_MESSAGE("copy(" << std::hex << ((ptrdiff_t)input) << ',' << ((ptrdiff_t)output) << std::dec << ',' << count << ')');
    483507        memcpy(output, input, count * sizeof(T));
    484508}
     
    488512void Array<BitBlock>::copy(const BitBlock * input, BitBlock * output, size_t count)
    489513{
    490     DEBUG_ARRAY_MESSAGE("Array<BitBlock>::copy(" << std::hex << ((ptrdiff_t)input) << ',' << ((ptrdiff_t)output) << std::dec << ',' << count << ')');
     514    DEBUG_ARRAY_MESSAGE("copy(" << std::hex << ((ptrdiff_t)input) << ',' << ((ptrdiff_t)output) << std::dec << ',' << count << ')');
    491515        while (count--)
    492516        {
     
    517541void Array<T>::memzero(T & ptr, size_t count)
    518542{
    519     memset(ptr, 0, count * sizeof(T));
     543    memset(&ptr, 0, count * sizeof(T));
    520544}
    521545
     
    570594T * Array<T>::allocate(const size_t size)
    571595{
     596    if (unlikely(size == 0)) return 0;
     597
    572598    T * ptr = new T[size];
    573599
    574     DEBUG_ARRAY_MESSAGE("Array<" << typeid(T).name() << ">::allocate(" << size << ") -> " << std::hex << ((ptrdiff_t)ptr) << std::dec);
     600    DEBUG_ARRAY_MESSAGE("allocate(" << size << ")=" << std::hex << ((ptrdiff_t)ptr) << std::dec);
    575601
    576602    return ptr;
     
    597623        #endif
    598624
    599     DEBUG_ARRAY_MESSAGE("Array<BitBlock>::allocate(" << size << ") -> " << std::hex << ((ptrdiff_t)ptr) << std::dec);
     625    DEBUG_ARRAY_MESSAGE("allocate(" << size << ") -> " << std::hex << ((ptrdiff_t)ptr) << std::dec);
    600626
    601627    return ptr;
     
    608634void Array<T>::deallocate(T * ptr)
    609635{
    610     DEBUG_ARRAY_MESSAGE("Array<" << typeid(T).name() << ">::deallocate(" << std::hex << ((ptrdiff_t)ptr) << std::dec << ')');
     636    DEBUG_ARRAY_MESSAGE("deallocate(" << std::hex << ((ptrdiff_t)ptr) << std::dec << ')');
    611637    if (ptr)
    612638    {
     
    619645void Array<BitBlock>::deallocate(BitBlock * ptr)
    620646{
    621     DEBUG_ARRAY_MESSAGE("Array<BitBlock>::deallocate(" << std::hex << ((ptrdiff_t)ptr) << std::dec << ')');
     647    DEBUG_ARRAY_MESSAGE("deallocate(" << std::hex << ((ptrdiff_t)ptr) << std::dec << ')');
    622648
    623649        if (ptr)
     
    636662Array<T>::~Array() { }
    637663
     664#if defined(PRINT_ARRAY_DEBUG_MESSAGES) && defined(PRINT_DEBUG_MESSAGE)
     665template<typename T>
     666IDISA_ALWAYS_INLINE
     667char * Array<T>::name()
     668{
     669    const char * mangledName = typeid(T).name();
     670    size_t demangledNameSz = 1024;
     671    char * demangledName = static_cast<char*>(malloc(demangledNameSz));
     672    int status = -1;
     673    abi::__cxa_demangle(mangledName, demangledName, &demangledNameSz, &status);
     674    if (status)
     675    {
     676        char * out = demangledName;
     677        for (const char * p = mangledName; *p; p++, out++)
     678        {
     679            *out = *p;
     680        }
     681        *out = 0;
     682    }
     683    return demangledName;
     684}
     685#endif
     686
    638687#endif // ARRAY_HPP
  • icXML/icXML-devel/src/icxmlc/BitTracker.hpp

    r2720 r3563  
    77/*
    88 * @author Nigel Medforth, nigelm -at- interational-characters.com
    9  * @version $Id: BitTracker.hpp 207 2012-12-02 20:38:22Z robc $
     9 * @version $Id: BitTracker.hpp 371 2013-09-05 21:51:18Z nigelm $
    1010 *
    1111 */
     
    2626        BitTracker();
    2727
     28    BitTracker(const size_t position);
     29
    2830        BitTracker(const BitTracker & tracker);
    2931
    3032        BitTracker& operator=(const BitTracker& tracker);
    3133
    32         void set(const int64_t value);
     34    void set(const size_t value);
    3335
    3436        bool append(const BitBlock value);
    3537
    36         uint64_t distance();
     38    size_t distance();
    3739
    3840private:
    3941
    40         BitBlock                      _lastNonEmptyBlock;
    41         uint64_t                      _blocksAfterLastNonEmptyBlock;
     42    BitBlock                      fLastNonEmptyBlock;
     43    size_t                        fBlocksAfterLastNonEmptyBlock;
    4244};
    4345
    44 IDISA_ALWAYS_INLINE
    45 BitTracker::BitTracker()
    46         : _lastNonEmptyBlock(simd<1>::constant<1>())
    47         , _blocksAfterLastNonEmptyBlock(0)
     46inline BitTracker::BitTracker()
     47: fLastNonEmptyBlock(simd<1>::constant<1>())
     48, fBlocksAfterLastNonEmptyBlock(0)
    4849{
    4950
    5051}
    5152
     53inline BitTracker::BitTracker(const size_t position)
     54: fLastNonEmptyBlock(bitblock::srl(simd<1>::constant<1>(), convert(position & (BLOCK_SIZE - 1))))
     55, fBlocksAfterLastNonEmptyBlock(position >> LOG_2_BLOCK_SIZE)
     56{
     57
     58}
     59
     60
    5261IDISA_ALWAYS_INLINE
    5362BitTracker::BitTracker(const BitTracker & tracker)
    54         : _lastNonEmptyBlock(tracker._lastNonEmptyBlock)
    55         , _blocksAfterLastNonEmptyBlock(tracker._blocksAfterLastNonEmptyBlock)
     63: fLastNonEmptyBlock(tracker.fLastNonEmptyBlock)
     64, fBlocksAfterLastNonEmptyBlock(tracker.fBlocksAfterLastNonEmptyBlock)
    5665{
    5766
     
    6170BitTracker& BitTracker::operator=(const BitTracker& tracker)
    6271{
    63         _lastNonEmptyBlock = tracker._lastNonEmptyBlock;
    64         _blocksAfterLastNonEmptyBlock = tracker._blocksAfterLastNonEmptyBlock;
     72    fLastNonEmptyBlock = tracker.fLastNonEmptyBlock;
     73    fBlocksAfterLastNonEmptyBlock = tracker.fBlocksAfterLastNonEmptyBlock;
    6574        return *this;
    6675}
    6776
    6877IDISA_ALWAYS_INLINE
    69 void BitTracker::set(const int64_t value)
     78void BitTracker::set(const size_t value)
    7079{
    71         _blocksAfterLastNonEmptyBlock =
    72                 value >> LOG_2_BLOCK_SIZE;
    73 
    74         _lastNonEmptyBlock =
    75                 bitblock::srl(simd<1>::constant<1>(), convert(value & (BLOCK_SIZE - 1)));
     80    if (CONST_EXPR(value == 0))
     81    {
     82        fBlocksAfterLastNonEmptyBlock = 0;
     83        fLastNonEmptyBlock = simd<1>::constant<1>();
     84    }
     85    else
     86    {
     87        fBlocksAfterLastNonEmptyBlock = value >> LOG_2_BLOCK_SIZE;
     88        fLastNonEmptyBlock = bitblock::srl(simd<1>::constant<1>(), convert(value & (BLOCK_SIZE - 1)));
     89    }
    7690}
    7791
     
    8195        if (bitblock::any(value))
    8296        {
    83                 _lastNonEmptyBlock = value;
    84                 _blocksAfterLastNonEmptyBlock = 0;
     97        fLastNonEmptyBlock = value;
     98        fBlocksAfterLastNonEmptyBlock = 0;
    8599                return 1;
    86100        }
    87101        else
    88102        {
    89                 _blocksAfterLastNonEmptyBlock++;
     103        fBlocksAfterLastNonEmptyBlock++;
    90104                return 0;
    91105        }
     
    93107
    94108IDISA_ALWAYS_INLINE
    95 uint64_t BitTracker::distance()
     109size_t BitTracker::distance()
    96110{
    97         return (_blocksAfterLastNonEmptyBlock << LOG_2_BLOCK_SIZE) |
    98                    (count_reverse_zeroes(_lastNonEmptyBlock));
     111    return (fBlocksAfterLastNonEmptyBlock << LOG_2_BLOCK_SIZE) | (count_reverse_zeroes(fLastNonEmptyBlock));
    99112}
    100113
  • icXML/icXML-devel/src/icxmlc/HashTable.hpp

    r3103 r3563  
    77/*
    88 * @author Nigel Medforth, nigelm -at- interational-characters.com
    9  * @version $Id: HashTable.hpp 282 2013-04-04 21:06:57Z nigelm $
     9 * @version $Id: HashTable.hpp 360 2013-06-24 20:37:04Z nigelm $
    1010 *
    1111 */
     
    2222XERCES_CPP_NAMESPACE_BEGIN
    2323
     24#define IS_BASE_2(x) CONST_EXPR((x & (x - 1)) == 0)
     25
    2426// QUESTION: is it better to use the gid concept to allow for internal list reorganization or to use a "memory pool"
    2527// to store everything and return pointers to immutable entries?
     
    2729/// -----------------------------------------------------------------------------------------------------------------
    2830
    29 template <class T, typename Char, unsigned int defaultSize, bool userIndexedList = false>
     31template <class T, typename Char, size_t defaultSize, bool userIndexedList = false>
    3032class HashTable
    3133{
     
    6264
    6365        IDISA_ALWAYS_INLINE
    64         gid_t indexOf(const T * entry) const
    65         {
    66             const ptrdiff_t index = entry - &_list[0];
    67             return static_cast<gid_t>(index);
    68         }
     66        gid_t indexOf(const T * entry) const;
    6967
    7068                // NOTE: it is NOT safe to store pointers to these entries; they will
     
    8280                }
    8381
     82        const size_t capacity() const
     83        {
     84            return _list.capacity();
     85        }
     86
    8487                size_t count() const
    8588                {
     
    8790                }
    8891
     92        void resizeToFit(const size_t size);
     93
    8994                void flush();
    9095
     
    9398                IDISA_ALWAYS_INLINE
    9499                bool rebuild();
    95 
    96                 IDISA_ALWAYS_INLINE
    97                 bool expand();
    98100
    99101                bool repopulate();
     
    133135                }
    134136
    135                 IDISA_ALWAYS_INLINE
    136                 size_t hashA(const Char * key, const hash_t length) const
    137                 {
    138             return Murmur3<Char>::hash(key, length, _seed0, _table.capacity());
    139                 }
    140 
    141 
    142                 IDISA_ALWAYS_INLINE
    143                 size_t hashB(const Char * key, const hash_t length) const
    144                 {
    145             return Murmur3<Char>::hash(key, length, _seed1, _table.capacity());
    146                 }
    147 
    148                 IDISA_ALWAYS_INLINE
    149                 bool equals(const T * entry, const Char * key, const hash_t length) const
    150                 {
    151                         return likely(entry != 0) ? entry->equals(key, length) : 0;
     137        IDISA_ALWAYS_INLINE
     138        hash_t modByTableSize(hash_t k) const
     139        {
     140            if (IS_BASE_2(defaultSize))
     141            {
     142                k &= (_table.capacity() - 1);
     143            }
     144            else
     145            {
     146                k %= _table.capacity();
     147            }
     148            return k;
     149        }
     150
     151                IDISA_ALWAYS_INLINE
     152        hash_t hashA(const Char * key, const hash_t length) const
     153                {
     154            return modByTableSize(Murmur3<Char>::hash(key, length, _seed0));
     155                }
     156
     157
     158                IDISA_ALWAYS_INLINE
     159        hash_t hashB(const Char * key, const hash_t length) const
     160                {
     161            return modByTableSize(Murmur3<Char>::hash(key, length, _seed1));
     162                }
     163
     164                IDISA_ALWAYS_INLINE
     165        bool equals(const size_t idx, const Char * key, const hash_t length) const
     166                {
     167            if (likely(idx < _table.capacity()))
     168            {
     169                const T * entry = _table[idx];
     170                if (likely(entry != 0))
     171                {
     172                    return entry->equals(key, length);
     173                }
     174            }
     175            return false;
    152176                }
    153177
    154178        private:
    155179
    156                 DynamicArray<T*, defaultSize>                                                                   _table;
     180        DynamicArray<T*, defaultSize * 2>                               _table;
    157181                DynamicArray<T, defaultSize>                                                                    _list;
    158182                size_t                                                                                                                  _count;
     
    163187
    164188#define HASH_TABLE(retType) \
    165         template <class T, typename Char, unsigned int defaultSize, bool userIndexedList> \
     189    template <class T, typename Char, size_t defaultSize, bool userIndexedList> \
    166190        IDISA_ALWAYS_INLINE \
    167191        retType \
     
    169193
    170194/// -----------------------------------------------------------------------------------------------------------------
     195
     196HASH_TABLE(gid_t)::
     197indexOf(const T * entry) const
     198{
     199    const ptrdiff_t index = entry - &_list[0];
     200    return static_cast<gid_t>(index);
     201}
    171202
    172203HASH_TABLE(gid_t)::
     
    181212
    182213        hash_t idx = hashA(key, length);
    183         if (likely(equals(_table[idx], key, length)))
     214    if (likely(equals(idx, key, length)))
     215        {
     216        return indexOf(_table[idx]);
     217        }
     218
     219        idx = hashB(key, length);
     220    if (likely(equals(idx, key, length)))
    184221        {
    185222                return indexOf(_table[idx]);
    186223        }
    187 
    188         idx = hashB(key, length);
    189         if (likely(equals(_table[idx], key, length)))
    190         {
    191                 return indexOf(_table[idx]);
    192         }
    193 
    194224        return -1;
    195225}
     
    208238                // what if the length of the key is 0, or it's unaligned? will the function still work?
    209239
    210         // DEBUG_MESSAGE(std::hex << (size_t)(this) << std::dec << ".add(" << item.getKey() << ')')
    211 
    212240                if (unlikely(_count == _list.capacity()))
    213241                {
    214                         expand();
     242            resizeToFit(_list.capacity() * 2);
    215243                }
    216244
     
    270298                if (unlikely(index >= _list.capacity()))
    271299                {
    272                         expand();
     300            resizeToFit(max<size_t>(_list.capacity() * 2, index));
    273301                }
    274302
     
    330358//    regenerate_seeds();
    331359//    if (clear_and_repopulate()) return 1;
     360
    332361
    333362    _table.resizeToFit(0, _table.capacity() * 2);
     
    421450/// -----------------------------------------------------------------------------------------------------------------
    422451
    423 HASH_TABLE(bool)::
    424 expand()
    425 {
    426     _list.resizeToFit(_list.capacity(), _list.capacity() * 2);
    427     DEBUG_MESSAGE("HashTable::expand() -> list.capacity=" << _list.capacity())
     452HASH_TABLE(void)::
     453resizeToFit(const size_t size)
     454{
     455    // If we're resizing the internal list, we'll likely need to expand the table itself to suit. Just expand both and
     456    // repopulate the hash table. Note: since the table contains pointers to entries in the list, this also corrects
     457    // the fact the table would be refering to the 'old' objects prior to being repopulated.
     458    _list.resizeToFit(_list.capacity(), size);
    428459    _table.resizeToFit(0, _table.capacity() * 2);
    429     DEBUG_MESSAGE("HashTable::expand() -> table.capacity=" << _table.capacity())
    430     return repopulate();
     460    repopulate();
    431461}
    432462
    433463XERCES_CPP_NAMESPACE_END
    434464
     465#undef IS_BASE_2
    435466#undef HASH_TABLE
    436467
  • icXML/icXML-devel/src/icxmlc/PopCounter.hpp

    r2720 r3563  
    88/*
    99 * @author Nigel Medforth, nigelm -at- interational-characters.com
    10  * @version $Id: PopCounter.hpp 207 2012-12-02 20:38:22Z robc $
     10 * @version $Id: PopCounter.hpp 371 2013-09-05 21:51:18Z nigelm $
    1111 *
    1212 */
     
    3131                PopCounter();
    3232
    33                 PopCounter(const uint64_t popCount);
     33        PopCounter(const size_t popCount);
    3434
    3535                PopCounter(const PopCounter<COUNTERS>&);
     
    3737                PopCounter<COUNTERS>& operator=(const PopCounter<COUNTERS>& counter);
    3838
    39                 void set(const uint64_t popCount);
     39        void set(const size_t popCount);
    4040
    41                 void tally(const BitBlock value);
     41        void set(const BitBlock value);
    4242
    43                 uint64_t count();
     43        void tally(const BitBlock & value);
     44
     45        size_t count();
    4446
    4547        private:
     
    5355                );
    5456
    55                 uint64_t   _pop_count;
    56                 BitBlock   _pop_counters[COUNTERS];
     57        size_t      fPopCount;
     58        BitBlock    fPopCounters[COUNTERS];
    5759};
    5860
     
    6971POP_COUNTER()::
    7072PopCounter()
    71 : _pop_count(0)
     73: fPopCount(0)
    7274{
    7375        for (unsigned int i = 0; i < COUNTERS; i++)
    7476        {
    75                 _pop_counters[i] = simd<1>::constant<0>();
     77        fPopCounters[i] = simd<1>::constant<0>();
    7678        }
    7779}
    7880
    7981POP_COUNTER()::
    80 PopCounter(const uint64_t popCount)
    81 : _pop_count(popCount)
     82PopCounter(const size_t popCount)
     83: fPopCount(popCount)
    8284{
    8385        for (unsigned int i = 0; i < COUNTERS; i++)
    8486        {
    85                 _pop_counters[i] = simd<1>::constant<0>();
     87        fPopCounters[i] = simd<1>::constant<0>();
    8688        }
    8789}
     
    8991POP_COUNTER()::
    9092PopCounter(const PopCounter<COUNTERS>& counter)
    91 : _pop_count(counter._pop_count)
     93: fPopCount(counter.fPopCount)
    9294{
    9395        for (unsigned int i = 0; i < COUNTERS; i++)
    9496        {
    95                 _pop_counters[i] = counter._pop_counters[i];
     97        fPopCounters[i] = counter.fPopCounters[i];
    9698        }
    9799}
     
    100102operator=(const PopCounter<COUNTERS>& counter)
    101103{
    102         _pop_count = counter._pop_count;
     104    fPopCount = counter.fPopCount;
    103105        for (unsigned int i = 0; i < COUNTERS; i++)
    104106        {
    105                 _pop_counters[i] = counter._pop_counters[i];
     107        fPopCounters[i] = counter.fPopCounters[i];
    106108        }
    107109        return *this;
     
    109111
    110112POP_COUNTER(void)::
    111 set(const uint64_t popCount)
     113set(const BitBlock value)
    112114{
    113         _pop_count = popCount;
     115    fPopCount = 0;
     116    fPopCounters[0] = value;
     117    for (unsigned int i = 1; i < COUNTERS; i++)
     118    {
     119        fPopCounters[i] = simd<1>::constant<0>();
     120    }
     121}
     122
     123POP_COUNTER(void)::
     124set(const size_t popCount)
     125{
     126    fPopCount = popCount;
    114127        for (unsigned int i = 0; i < COUNTERS; i++)
    115128        {
    116                 _pop_counters[i] = simd<1>::constant<0>();
     129        fPopCounters[i] = simd<1>::constant<0>();
    117130        }
    118131}
     
    126139
    127140POP_COUNTER(void)::
    128 tally(const BitBlock value)
     141tally(const BitBlock & value)
    129142{
    130143        if (COUNTERS == 0)
    131144        {
    132145                // this comparison ought to be removed at compile time
    133                 _pop_count += bitblock::popcount(value);
     146        fPopCount += bitblock::popcount(value);
    134147        }
    135148        else if (bitblock::any(value))
     
    138151                for (unsigned int i = 0; i < COUNTERS; i++)
    139152                {
    140                         half_add(_pop_counters[i], carry, _pop_counters[i], carry);
     153            half_add(fPopCounters[i], carry, fPopCounters[i], carry);
    141154                }
    142155                if (unlikely(bitblock::any(carry)))
    143156                {
    144157                        count();
    145                         _pop_count += (bitblock::popcount(carry) << COUNTERS);
     158            fPopCount += (bitblock::popcount(carry) << COUNTERS);
    146159                }
    147160        }
    148161}
    149162
    150 POP_COUNTER(uint64_t)::
     163POP_COUNTER(size_t)::
    151164count()
    152165{
    153166        for (unsigned int i = 0; i < COUNTERS; i++)
    154167        {
    155                 _pop_count += (bitblock::popcount(_pop_counters[i]) << i);
     168        fPopCount += (bitblock::popcount(fPopCounters[i]) << i);
    156169        }
    157170        for (unsigned int i = 0; i < COUNTERS; i++)
    158171        {
    159                 bitblock::store_aligned(simd<1>::constant<0>(), &_pop_counters[i]);
     172        bitblock::store_aligned(simd<1>::constant<0>(), &fPopCounters[i]);
    160173        }
    161         return _pop_count;
     174    return fPopCount;
    162175}
    163176
  • icXML/icXML-devel/src/icxmlc/XMLConfig.hpp

    r3151 r3563  
    77/*
    88 * @author Nigel Medforth, nigelm -at- interational-characters.com
    9  * @version $Id: XMLConfig.hpp 302 2013-05-04 03:48:19Z nigelm $
     9 * @version $Id: XMLConfig.hpp 384 2013-10-21 22:28:13Z nigelm $
    1010 *
    1111 */
     
    2424
    2525#ifndef PRINT_DEBUG_IGNORE_TRANSITION_STREAM_MESSAGES
    26 //#define PRINT_DEBUG_IGNORE_TRANSITION_STREAM_MESSAGES
     26#define PRINT_DEBUG_IGNORE_TRANSITION_STREAM_MESSAGES
    2727#endif
    2828
    2929#ifndef PRINT_DEBUG_IGNORE_GRAMMAR_MESSAGES
    30 //#define PRINT_DEBUG_IGNORE_GRAMMAR_MESSAGES
     30#define PRINT_DEBUG_IGNORE_GRAMMAR_MESSAGES
    3131#endif
    3232
     
    3636
    3737#ifndef PRINT_DEBUG_IGNORE_SYMBOL_STREAM_MESSAGES
    38 //#define PRINT_DEBUG_IGNORE_SYMBOL_STREAM_MESSAGES
     38#define PRINT_DEBUG_IGNORE_SYMBOL_STREAM_MESSAGES
     39#endif
     40
     41#ifndef PRINT_DEBUG_IGNORE_REFERENCE_STREAM_MESSAGES
     42#define PRINT_DEBUG_IGNORE_REFERENCE_STREAM_MESSAGES
    3943#endif
    4044
     
    8993#if !defined(ICXML_ENABLE_VERSION1_1)
    9094#define ICXML_ENABLE_VERSION1_1  // to safely turn this on, any symbol ending with a NEL must be 'truncated' to remove the erroneous bytes.
    91 #endif
    92 
    93 #if !defined(IGNORE_DEFAULT_ATTRIBUTES)
    94 // #define IGNORE_DEFAULT_ATTRIBUTES
    9595#endif
    9696
     
    136136
    137137        #include <simd-lib/bitblock.hpp>
     138    #include <icxmlc/endian.h>
     139    //#include <PapiCounter.hpp>
     140
     141    #if defined(BOOST_LITTLE_ENDIAN)
     142    #define BYTE_OFFSET(x) (x)
     143    #elif defined(BOOST_BIG_ENDIAN)
     144    #define BYTE_OFFSET(x) (3 - x)
     145    #elif defined(BOOST_PDP_ENDIAN)
     146    #define BYTE_OFFSET(x) ((x + 2) & 3)
     147    #endif
    138148
    139149    typedef ScanWord scanword_t;
     
    159169    template <> struct CharType<4> {typedef XMLUInt32 T;};
    160170
    161 
    162171        /************************************ BUFFER SIZE CONFIGURATIONS **************************************/
    163172
    164     #define INITIAL_CONTENT_BUFFER_SIZE (16 * 1024)
    165 
    166     #define BUFFER_BLOCKS (INITIAL_CONTENT_BUFFER_SIZE / BLOCK_SIZE)
     173    #ifndef SEGMENT_SIZE
     174    #define SEGMENT_SIZE (16 * 1024)
     175    #endif
     176
     177    #define BUFFER_BLOCKS (SEGMENT_SIZE / BLOCK_SIZE)
     178
     179//    #define STRING2(x) #x
     180//    #define STRING(x) STRING2(x)
     181//    #pragma message "XMLConfig::SEGMENT_SIZE = " STRING(SEGMENT_SIZE)
    167182
    168183    #define INITIAL_SYMBOL_TABLE_CAPACITY 64    // NOTE MUST BE A POWER OF 2; TODO: investigate whether prime numbers are better given the cost of the mod
     
    180195        #define GET_CONTEXT_ID_FOR_EACH_ELEMENT
    181196
    182         #if INITIAL_CONTENT_BUFFER_SIZE > (64 * 1024)
    183         #define USE_HEAP_ALLOCATION_FOR_XML_PARSER
    184         #endif
    185 
    186197    typedef CharType<(CONST_LOG_2(BUFFER_BLOCKS) + 23) / 24>::T MarkupCountType; // 24 = bits per byte (8) * minimum length of any piece of markup (3)
     198
     199    #if ((SEGMENT_SIZE * 2) <= 0xFF)
     200    typedef int8_t LineColumnDiffType;
     201    #elif ((SEGMENT_SIZE * 2) <= 0xFFFF)
     202    typedef int16_t LineColumnDiffType;
     203    #elif ((SEGMENT_SIZE * 2) <= 0xFFFFFFFF)
     204    typedef int32_t LineColumnDiffType;
     205    #else
     206    typedef int64_t LineColumnDiffType;
     207    #define LINE_COLUMN_TRACKER_USES_RAW_NUMBERS
     208    #endif
    187209
    188210        /* PREFETCH */
     
    406428        }
    407429
     430        template <>
     431        inline void print_register<ScanWord>(const char * var_name, ScanWord v)
     432        {
     433            char output[sizeof(ScanWord) * 3 + 1] = {0};
     434
     435            const char hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7'
     436                                 , '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
     437
     438            union ScanWordArray {
     439                ScanWord _sw;
     440                uint8_t _8[sizeof(ScanWord)/sizeof(uint8_t)];
     441            };
     442
     443
     444            ScanWordArray value;
     445            value._sw = v;
     446
     447            for(size_t i = 0; i < sizeof(ScanWord); i++)
     448            {
     449                const char c = value._8[i];
     450                const size_t offset = (sizeof(ScanWord) - 1 - i) * 3;
     451                output[offset] = hex[(c & 0xF0) >> 4];
     452                output[offset + 1] = hex[c & 0x0F];
     453                output[offset + 2] = ' ';
     454            }
     455            output[sizeof(ScanWord) * 3] = 0;
     456
     457            std::clog << std::setw(40) << var_name << std::setw(0) << " = " << output << std::endl;
     458        }
     459
    408460        #else
    409461                #define DEBUG_MESSAGE(MSG)
     
    434486    #endif
    435487
     488    #if !defined(PRINT_DEBUG_IGNORE_REFERENCE_STREAM_MESSAGES)
     489        #define DEBUG_REFERENCE_MESSAGE(MSG) DEBUG_MESSAGE(MSG)
     490    #else
     491        #define DEBUG_REFERENCE_MESSAGE(MSG)
     492    #endif
     493
    436494    #if !defined(PRINT_DEBUG_IGNORE_WELL_FORMEDNESS_MESSAGES)
    437495        #define DEBUG_WELL_FORMEDNESS_MESSAGE(MSG) DEBUG_MESSAGE(MSG)
     
    465523
    466524        IDISA_ALWAYS_INLINE
    467         static void store_aligned_bypass_cache(const BitBlock reg, BitBlock * const output)
    468         {
    469                 #ifndef IGNORE_CACHE_BYPASS
    470                 _mm_stream_si128(output, reg);
    471                 #else
    472                 bitblock::store_aligned(reg, output);
    473                 #endif
    474         }
    475 
    476         IDISA_ALWAYS_INLINE
    477525        static void load_fence()
    478526        {
     
    490538        }
    491539
    492     IDISA_ALWAYS_INLINE
    493     static BitBlock bitblock_set(const size_t pos)
    494     {
    495         ubitblock temp = { simd<1>::constant<0>() };
    496         #ifdef __ARCH_64
    497         temp._64[pos >> 6] = static_cast<uint64_t>(1) << (pos & 63);
    498         #else
    499         temp._32[pos >> 5] = static_cast<uint32_t>(1) << (pos & 31);
    500         #endif
    501         return temp._128;
    502     }
    503 
    504 #endif
     540
     541#endif
  • icXML/icXML-devel/src/icxmlc/XMLDefaultCharacterSetAdapter.cpp

    r3103 r3563  
    77/*
    88 * @author Nigel Medforth, nigelm -at- interational-characters.com
    9  * @version $Id: XMLDefaultCharacterSetAdapter.cpp 296 2013-04-25 23:53:07Z nigelm $
     9 * @version $Id: XMLDefaultCharacterSetAdapter.cpp 371 2013-09-05 21:51:18Z nigelm $
    1010 *
    1111 */
     
    2727// ---------------------------------------------------------------------------
    2828
    29 XMLCh * XMLDefaultCharacterSetAdapter::parse
     29void XMLDefaultCharacterSetAdapter::parse
    3030(
    3131    const XMLByte * const               input
    3232    , const size_t              avail
    3333    , const bool                                noMore
    34     ,       XMLCh *             contentStream
    35     ,           gid_t *             symbolStream
    36     ,           size_t &            symbolCount
    37     ,           gid_t *             referenceStream
    38     ,           size_t &            referenceCount
    39     ,const XMLCh **             stringEndStream
    40     ,       size_t &            stringEndCount
    41     ,       size_t &            markupCount
     34    , XMLParser &               parser
    4235    ,           size_t &            bytesEaten
    4336)
     
    4538    #ifdef PRINT_DEBUG_MESSAGE
    4639    const char * transcoderTypeName = typeid(fInputTranscoder).name();
     40    const char * demangledTranscoderTypeName = 0;
    4741    #ifdef __GNUC__
    4842    int status;
    49     transcoderTypeName = abi::__cxa_demangle(transcoderTypeName, 0, 0, &status);
     43    demangledTranscoderTypeName = abi::__cxa_demangle(transcoderTypeName, 0, 0, &status);
    5044    #endif
     45    DEBUG_MESSAGE("XMLDefaultCharacterSetAdapter: transcoding " << fInputTranscoder.getEncodingName() << " using " << (demangledTranscoderTypeName ? demangledTranscoderTypeName : transcoderTypeName))
     46    delete demangledTranscoderTypeName;
    5147    #endif
    5248
    53     DEBUG_MESSAGE("XMLDefaultCharacterSetAdapter: transcoding " << fInputTranscoder.getEncodingName() << " using " << transcoderTypeName)
     49    DEBUG_MESSAGE(" --- fTranscodedOffset=" << fTranscodedOffset);
    5450
    5551    XMLSize_t untranscodedBytesEaten;
     
    6056            avail,
    6157            fTranscodedInput + fTranscodedOffset,
    62             INITIAL_CONTENT_BUFFER_SIZE - fTranscodedOffset,
     58            SEGMENT_SIZE - fTranscodedOffset,
    6359            untranscodedBytesEaten
    6460        ) + fTranscodedOffset;
     
    7369    size_t transcodedCharsEaten = 0;
    7470
    75     XMLCh * contentStreamPtr =
    76         XMLUTF16CharacterSetAdapter::parseInternal
    77         (
    78             fTranscodedInput
    79             , transcodedCharsAvail
    80             , noMore
    81             , contentStream
    82             , symbolStream
    83             , symbolCount
    84             , referenceStream
    85             , referenceCount
    86             , stringEndStream
    87             , stringEndCount
    88             , markupCount
    89             , transcodedCharsEaten
    90         );
     71    XMLUTF16CharacterSetAdapter::parseInternal
     72    (
     73        fTranscodedInput
     74        , transcodedCharsAvail
     75        , noMore
     76        , parser
     77        , transcodedCharsEaten
     78    );
    9179
    9280    this->fSymbolTable->setTranscoder(&fInputTranscoder);
    9381    this->fReferenceTable->setTranscoder(&fInputTranscoder);
    94 
    95     assert (transcodedCharsEaten <= transcodedCharsAvail);
    9682
    9783    if (transcodedCharsEaten < transcodedCharsAvail)
     
    10591    }
    10692
    107     // return the final content end pointer
    108     return contentStreamPtr;
    10993}
    11094
  • icXML/icXML-devel/src/icxmlc/XMLDefaultCharacterSetAdapter.hpp

    r3103 r3563  
    4747    }
    4848
    49     virtual XMLCh * parse
     49    virtual void parse
    5050    (
    5151        const XMLByte * const           input
    5252        , const size_t              avail
    5353        , const bool                            noMore
    54         ,       XMLCh *             contentStream
    55         ,               gid_t *             symbolStream
    56         ,               size_t &            symbolCount
    57         ,               gid_t *             referenceStream
    58         ,               size_t &            referenceCount
    59         ,const XMLCh **             stringEndStream
    60         ,       size_t &            stringEndCount
    61         ,       size_t &            markupCount
     54        , XMLParser &               parser
    6255        ,               size_t &            bytesEaten
    6356    );
     
    7063    XMLDefaultCharacterSetAdapter& operator=(const XMLDefaultCharacterSetAdapter&);
    7164
    72     XMLCh                                                                 fTranscodedInput[INITIAL_CONTENT_BUFFER_SIZE];
     65    XMLCh                                                                 fTranscodedInput[SEGMENT_SIZE];
    7366    size_t                                                                fTranscodedOffset;
    7467
  • icXML/icXML-devel/src/icxmlc/XMLGrammarResolver.hpp

    r3104 r3563  
    77/*
    88 * @author Nigel Medforth, nigelm -at- interational-characters.com
    9  * @version $Id: XMLGrammarResolver.hpp 252 2013-02-07 03:32:22Z nigelm $
     9 * @version $Id: XMLGrammarResolver.hpp 388 2013-10-29 21:25:27Z nigelm $
    1010 *
    1111 */
     
    4848Grammar * XMLGrammarResolver::getGrammar(const unsigned int uriId) const
    4949{
     50    DEBUG_GRAMMAR_MESSAGE("XMLGrammarResolver::getGrammar(" << uriId << ')')
    5051        if (likely(uriId < fList.capacity()))
    5152        {
     
    5758void XMLGrammarResolver::setGrammar(const unsigned int uriId, Grammar * grammar)
    5859{
     60    DEBUG_GRAMMAR_MESSAGE("XMLGrammarResolver::setGrammar(" << uriId << ',' << grammar << ") cap=" << fList.capacity())
    5961        if (unlikely(uriId >= fList.capacity()))
    60         {
    61                 fList.resizeToFit(uriId);
    62 
    63                 DEBUG_MESSAGE("fList.capacity()=" << fList.capacity())
     62        {       
     63        fList.resizeToFit(max<size_t>(uriId, fList.capacity() * 2));
     64        DEBUG_MESSAGE("cap'=" << fList.capacity())
    6465        }
    6566        fList[uriId] = grammar;
  • icXML/icXML-devel/src/icxmlc/XMLLineColTracker.hpp

    r2720 r3563  
    77/*
    88 * @author Nigel Medforth, nigelm -at- interational-characters.com
    9  * @version $Id: XMLLineColTracker.hpp 207 2012-12-02 20:38:22Z robc $
     9 * @version $Id: XMLLineColTracker.hpp 371 2013-09-05 21:51:18Z nigelm $
    1010 *
    1111 */
     
    1616#define XERCESC_INCLUDE_GUARD_XMLLINECOLTRACKER_HPP
    1717
    18 #include <icxmlc/clog2.h>
    19 #include <simd-lib/bitblock.hpp>
    2018#include <icxmlc/PopCounter.hpp>
    2119#include <icxmlc/BitTracker.hpp>
     
    2422XERCES_CPP_NAMESPACE_BEGIN
    2523
     24class XMLParser;
     25
    2626class XMLLineColTracker
    2727{
    28   public:
     28    friend class XMLUTF8CharacterSetAdapter;
     29    friend class XMLUTF16CharacterSetAdapter;
    2930
    30                 XMLLineColTracker();
     31    public:
    3132
    32                 XMLLineColTracker(const XMLLineColTracker&);
     33        XMLLineColTracker(const XMLFileLoc line, const XMLFileLoc column);
    3334
    34                 void set(const XMLFileLoc line, const XMLFileLoc column);
     35        void reset();
    3536
    36                 void next(const BitBlock newLine, const BitBlock skipMask);
     37        void write(const size_t index, const BitBlock lineFeed, const BitBlock skipMask);
    3738
    38                 XMLLineColTracker& operator=(const XMLLineColTracker& tracker);
     39        void getErrorPosition(const size_t index, const size_t offset, XMLFileLoc & line, XMLFileLoc & column);
    3940
    40                 void advance();
     41        void writeLineColumnStream
     42        (
     43            const BitBlock *            delimiterStream
     44            , const size_t              count
     45            , LineColumnDiffType *      lineColumnStream
     46            , XMLFileLoc &              line
     47            , XMLFileLoc &              column
     48        );
    4149
    42                 void get
    43                 (
    44                         const unsigned int     position
    45                         , XMLFileLoc         & line
    46                         , XMLFileLoc         & column
    47                 );
     50    private:
    4851
    49                 void get
    50                 (
    51                         XMLFileLoc           & line
    52                         , XMLFileLoc         & column
    53                 );
     52        static ScanWord ScanLineFeedMask(const ScanWord lf, const ScanWord pos);
    5453
    55   private:
     54    private:
    5655
    57                 XMLFileLoc calculateSkipCount(const unsigned int position);
    58 
    59 
    60                 // TODO: if this is just a temporary storage line/col tracker,
    61                 // have popcounter set to 0 to eliminate the tally bit blocks?
    62                 BitBlock                      _currentLine;
    63                 PopCounter<3>                 _line;
    64                 BitTracker                    _column;
    65                 BitBlock                      _currentSkipMask;
    66                 PopCounter<1>                 _skip;
    67                 BitBlock                      _initialPartialSkipMask;
     56        BitBlock                      fAnySkipMask;
     57        BitBlock                      fLinefeedStream[BUFFER_BLOCKS];       
     58        BitBlock                      fSkipmaskStream[BUFFER_BLOCKS];       
     59        XMLFileLoc                    fLine;
     60        XMLFileLoc                    fColumn;
    6861};
    6962
    7063/// --------------------------------------------------------------------------- ///
    7164
    72 IDISA_ALWAYS_INLINE
    73 XMLLineColTracker::XMLLineColTracker()
    74         : _currentLine(simd<1>::constant<0>())
    75         , _line()
    76         , _column()
    77         , _currentSkipMask(simd<1>::constant<0>())
    78         , _skip()
    79         , _initialPartialSkipMask(simd<1>::constant<0>())
     65inline XMLLineColTracker::XMLLineColTracker(const XMLFileLoc line, const XMLFileLoc column)
     66: fAnySkipMask(simd<1>::constant<0>())
     67, fLine(line)
     68, fColumn(column)
    8069{
    8170
     
    8574
    8675IDISA_ALWAYS_INLINE
    87 XMLLineColTracker::XMLLineColTracker(const XMLLineColTracker & tracker)
    88         : _currentLine(tracker._currentLine)
    89         , _line(tracker._line)
    90         , _column(tracker._column)
    91         , _currentSkipMask(tracker._currentSkipMask)
    92         , _skip(tracker._skip)
    93         , _initialPartialSkipMask(tracker._initialPartialSkipMask)
     76void XMLLineColTracker::write(const size_t index, const BitBlock lineFeed, const BitBlock skipMask)
    9477{
    95 
     78    bitblock::store_aligned(lineFeed, fLinefeedStream + index);
     79    bitblock::store_aligned(skipMask, fSkipmaskStream + index);
     80    fAnySkipMask = simd_or(fAnySkipMask, skipMask);
    9681}
    97 
    98 /// --------------------------------------------------------------------------- ///
    99 
    100 IDISA_ALWAYS_INLINE
    101 XMLLineColTracker& XMLLineColTracker::operator=(const XMLLineColTracker& tracker)
    102 {
    103         _currentLine = tracker._currentLine;
    104         _line = tracker._line;
    105         _column = tracker._column;
    106         _currentSkipMask = tracker._currentSkipMask;
    107         _skip = tracker._skip;
    108         _initialPartialSkipMask = tracker._initialPartialSkipMask;
    109         return *this;
    110 }
    111 
    112 /// --------------------------------------------------------------------------- ///
    113 
    114 IDISA_ALWAYS_INLINE
    115 void XMLLineColTracker::set(const XMLFileLoc line, const XMLFileLoc column)
    116 {
    117         _currentLine = simd<1>::constant<0>();
    118         _line.set(line - 1);
    119         _column.set(column - 1);
    120         _currentSkipMask = simd<1>::constant<0>();
    121         _skip.set(0);
    122         _initialPartialSkipMask = simd<1>::constant<0>();
    123 }
    124 
    125 /// --------------------------------------------------------------------------- ///
    126 
    127 IDISA_ALWAYS_INLINE
    128 void XMLLineColTracker::next(const BitBlock newLine, const BitBlock skipMask)
    129 {
    130         _currentLine = newLine;
    131         _currentSkipMask = skipMask;
    132 }
    133 
    134 /// --------------------------------------------------------------------------- ///
    135 
    136 IDISA_ALWAYS_INLINE
    137 void XMLLineColTracker::advance()
    138 {
    139         if (_column.append(_currentLine))
    140         {
    141                 // at least one new line exists in this block
    142                 _line.tally(_currentLine);
    143                 _initialPartialSkipMask = _currentSkipMask;
    144                 _skip.set(0);
    145         }
    146         else
    147         {
    148                 // no new lines exist in this block
    149                 _skip.tally(_currentSkipMask);
    150         }
    151         _currentLine = simd<1>::constant<0>();
    152         _currentSkipMask = simd<1>::constant<0>();
    153 }
    154 
    155 /// --------------------------------------------------------------------------- ///
    156 
    157 IDISA_ALWAYS_INLINE
    158 void XMLLineColTracker::get
    159 (
    160         XMLFileLoc           & line
    161         , XMLFileLoc         & column
    162 )
    163 {
    164         // count up how many column positions we skip up to and including this block
    165         const unsigned int dist = _column.distance();
    166         _skip.tally
    167         (
    168                 simd_andc(_initialPartialSkipMask, mask_reverse_zeroes(dist & (BLOCK_SIZE - 1)))
    169         );
    170         _initialPartialSkipMask = simd<1>::constant<0>();
    171         // get the final line/column positions
    172         column = dist - _skip.count() + 1;
    173         line = _line.count() + 1;
    174 }
    175 
    176 /// --------------------------------------------------------------------------- ///
    177 
    178 IDISA_ALWAYS_INLINE
    179 void XMLLineColTracker::get
    180 (
    181         const unsigned int     position
    182         , XMLFileLoc         & line
    183         , XMLFileLoc         & column
    184 )
    185 {
    186         const BitBlock partialBlockMask = mask_forward_zeroes(position);
    187         const BitBlock partialCurrentLine = simd_andc(_currentLine, partialBlockMask);
    188         const BitBlock partialSkipMask = simd_andc(_currentSkipMask, partialBlockMask);
    189 
    190         // data dependant but predictable condition
    191         if (bitblock::any(partialCurrentLine))
    192         {
    193                 const unsigned int dist =
    194                         count_reverse_zeroes(partialCurrentLine);
    195                 const uint64_t skipCount =
    196                         bitblock::popcount(simd_andc(partialSkipMask, mask_reverse_zeroes(dist)));
    197                 // get the final line/column positions
    198                 line = _line.count() + bitblock::popcount(partialCurrentLine) + 1;
    199                 column = position + dist - BLOCK_SIZE + 1 - skipCount;
    200         }
    201         else // the last new line was in one of the previous blocks. find it.
    202         {
    203                 const unsigned int dist = _column.distance();
    204                 // count up how many column positions we skip up to this block
    205                 _skip.tally
    206                 (
    207                         simd_andc(_initialPartialSkipMask, mask_reverse_zeroes(dist & (BLOCK_SIZE - 1)))
    208                 );
    209                 _initialPartialSkipMask = simd<1>::constant<0>();
    210                 // count how many column positions we skip within this block
    211                 const uint64_t skipCount =
    212                         _skip.count() +
    213                         bitblock::popcount(partialSkipMask);
    214                 // set the final line/column positions
    215                 line = _line.count() + 1;
    216                 column = dist + position - skipCount + 1;
    217         }
    218 }
    219 
    220 /// --------------------------------------------------------------------------- ///
    221 
    222 
    223 
    22482
    22583XERCES_CPP_NAMESPACE_END
  • icXML/icXML-devel/src/icxmlc/XMLNameChars.hpp

    r3151 r3563  
    184184                    else
    185185                        return (codepoint >= 0xFDF0) & (codepoint <= 0xFFFD);
    186 //                default:
    187 //                    return codepoint <= 0xEFFFF;
     186                default:
     187                    UNREACHABLE
    188188            }
    189189        }
     
    229229                    else
    230230                        return (codepoint >= 0xFDF0) & (codepoint <= 0xFFFD);
    231 //                default:
    232 //                    return codepoint <= 0xEFFFF;
     231                default:
     232                    UNREACHABLE
    233233            }
    234234        }
  • icXML/icXML-devel/src/icxmlc/XMLNamespaceBindingSet.hpp

    r3103 r3563  
    77/*
    88 * @author Nigel Medforth, nigelm -at- interational-characters.com
    9  * @version $Id: XMLNamespaceBindingSet.hpp 276 2013-03-21 22:31:52Z nigelm $
     9 * @version $Id: XMLNamespaceBindingSet.hpp 389 2013-11-05 19:46:19Z nigelm $
    1010 *
    1111 */
     
    1919
    2020typedef ScanWord binding_t;
    21 
    22 #ifdef _MSC_VER
    23 #include <intrin.h> // _BitScanForward
    24 #endif
    25 
    2621class BindingSet;
    2722class BindingSetIterator;
     
    213208
    214209                IDISA_ALWAYS_INLINE
    215         static bool bittest(const binding_t bitArray, const binding_t pos)
    216                 {
    217                         #if defined(_MSC_VER) && defined(_M_X64)
    218                 return _bittest64((__int64*)&bitArray, pos);
    219                         #elif defined(_MSC_VER) && defined(_M_X86)
    220                 return _bittest(&bitArray, pos);
    221                         #else
    222                 // this ought to generate the bittest (bt) instruction if n
    223                 const binding_t ONE = 1;
    224                 return bitArray & (ONE << (pos & (BITS_PER_BINDING - 1)));
    225             #endif
     210        static bool bittest(const binding_t * a, const binding_t b)
     211                {
     212            bool retval;
     213            __asm__("bt %[b], %[a]; setb %b[retval]" : [retval] "=q" (retval) : [a] "mr" (*a), [b] "r" (b));
     214            return retval;
    226215                }
    227216
     
    414403                }
    415404
     405        IDISA_ALWAYS_INLINE
     406        void set(const binding_t value)
     407        {
     408            *this->_bindingSet = value;
     409        }
     410
    416411        private:
    417412
     
    435430bool FixedBindingSet::operator[](const binding_t id) const
    436431{
    437     return bittest(_bindingSet[id >> LOG_2_BITS_PER_BINDING], id);
     432    return bittest(_bindingSet, id);
    438433}
    439434
     
    519514bool FixedBindingSet::mask_and_extract(const FixedBindingSet & otherSet, const binding_t id) const
    520515{
    521         const binding_t idx = id >> LOG_2_BITS_PER_BINDING;
    522         ASSUME(idx == 0);
    523         const binding_t maskedSet = _bindingSet[idx] & otherSet._bindingSet[idx];
    524     return bittest(maskedSet, id);
     516    return bittest(_bindingSet, id) && bittest(otherSet._bindingSet, id);
    525517}
    526518
    527519bool FixedBindingSet::mask_and_extract(const BindingSet & otherSet, const binding_t id) const
    528520{
    529         const binding_t idx = id >> LOG_2_BITS_PER_BINDING;
    530         ASSUME(idx == 0);
    531         const binding_t maskedSet = _bindingSet[idx] & otherSet._bindingSet[idx];
    532     return bittest(maskedSet, id);
     521    return bittest(_bindingSet, id) && bittest(otherSet._bindingSet, id);
    533522}
    534523
     
    731720                        DEBUG_MESSAGE("BindingSets::increaseBitCapacity(" << minimum << ')')
    732721
     722            if (minimum < bitCapacity()) return;
     723
    733724                        //how many binding_t blocks do we have currently?
    734725                        const binding_t bitCapacity = this->bitCapacity() >> FixedBindingSet::LOG_2_BITS_PER_BINDING;
     
    772763                        DEBUG_MESSAGE("BindingSets::increaseSetCapacity(" << minumum << ')')
    773764
     765            if (minumum < setCapacity()) return;
     766
    774767                        //how many binding_t blocks do we have currently?
    775768                        const binding_t bitCapacity = this->bitCapacity() >> FixedBindingSet::LOG_2_BITS_PER_BINDING;
     
    777770
    778771                        //how many sets are needed?
    779                         const binding_t newSetCapacity =
    780                                 max
    781                                 (
    782                                         setCapacity * 2
    783                                         , minumum + (initialSetCount - minumum % initialSetCount)
    784                                 );
     772            const binding_t newSetCapacity = max(setCapacity * 2, minumum + (initialSetCount - minumum % initialSetCount));
    785773
    786774                        const binding_t capacity = bitCapacity * setCapacity;
     
    798786                        _setCapacity = newSetCapacity;
    799787                }
    800 
    801 
    802 //              IDISA_ALWAYS_INLINE
    803 //              void expand(const size_t minimumCapacity)
    804 //              {
    805 //                      DEBUG_MESSAGE("BindingSets::expand(" << minimumCapacity << ')')
    806 
    807 //                      // construct a new array with double the capacity for each set,
    808 //                      // and double the number of sets (i.e., 4x the current capacity).
    809 
    810 //                      // construct a new array with double the capacity for each set,
    811 //                      // and double the number of sets (i.e., 4x the current capacity).
    812 
    813 //                      const binding_t newCapacity = (capacity() * 4);
    814 //                      binding_t * newBindingSet = Array<binding_t>::allocate(newCapacity);
    815 
    816 //                      // copy the old data over into the expanded array into the appropriate positions
    817 //                      binding_t origOffset = 0;
    818 //                      const binding_t sizeOfBindingSet = (1 << _log2SizeOfBindingSet);
    819 
    820 //                      binding_t newOffset = 0;
    821 //                      const binding_t sizeOfNewBindingSet = (sizeOfBindingSet << 1);
    822 
    823 //                      do
    824 //                      {
    825 //                              binding_t i = 0;
    826 
    827 //                              for (; i < sizeOfBindingSet; i++)
    828 //                              {
    829 //                                      newBindingSet[newOffset + i] = _bindingSets[origOffset + i];
    830 //                              }
    831 //                              origOffset += sizeOfBindingSet;
    832 
    833 //                              for (; i < sizeOfNewBindingSet; i++)
    834 //                              {
    835 //                                      newBindingSet[newOffset + i] = 0;
    836 //                              }
    837 //                              newOffset += sizeOfNewBindingSet;
    838 //                      }
    839 //                      while (origOffset < capacity());
    840 
    841 //                      // set the new array in place and delete the old one if needbe
    842 //                      deallocateIfNecessary();
    843 //                      _bindingSets = newBindingSet;
    844 //                      _log2SizeOfBindingSet++;
    845 //              }
    846788
    847789                IDISA_ALWAYS_INLINE
     
    945887    public:
    946888
    947         MaskedBindingSetIterator(const FixedBindingSet & set, const FixedBindingSet & mask, const bool complement = true)
     889        MaskedBindingSetIterator(const FixedBindingSet & set, const FixedBindingSet & mask, const bool complement)
    948890        : fBindingSet(set._bindingSet)
    949891        , fMaskSet(mask._bindingSet)
     892        , fIterator(getIterator(0, complement))
     893        , fPos(0)
     894        , fComplement(complement)
    950895        , fCapacity(min(set._capacity, mask._capacity))
    951         , fIndex(0)
    952         , fIterator(getIterator(0))
    953         , fComplement(complement)
     896        , fIndex(0)       
    954897        {
    955898
     
    960903        {
    961904            fIndex = 0;
    962             fIterator = getIterator(0);
     905            fIterator = getIterator(0, fComplement);
    963906            return next();
    964907        }
     
    973916                    return 0;
    974917                }
    975                 fIterator = getIterator(fIndex);
     918                fIterator = getIterator(fIndex, fComplement);
    976919            }
    977920            fPos = (fIndex << FixedBindingSet::LOG_2_BITS_PER_BINDING) | scan_forward_zeroes(fIterator);
     
    988931
    989932        IDISA_ALWAYS_INLINE
    990         binding_t getIterator(size_t index) const
     933        binding_t getIterator(const size_t index, const bool complement) const
    991934        {
    992             return fBindingSet[index] & (fComplement ? ~fMaskSet[index] : fMaskSet[index]);
     935            if (complement)
     936            {
     937                return fBindingSet[index] &~ fMaskSet[index];
     938            }
     939            else
     940            {
     941                return fBindingSet[index] & fMaskSet[index];
     942            }
    993943        }
    994944
     
    998948        const binding_t *                               fBindingSet;
    999949        const binding_t *                               fMaskSet;
    1000         const binding_t                                 fCapacity;
    1001         binding_t                                               fIndex;
     950
    1002951        binding_t                                               fIterator;
    1003952        binding_t                                               fPos;
    1004953        const bool                      fComplement;
     954
     955        const binding_t                                 fCapacity;
     956        binding_t                                               fIndex;
    1005957};
    1006958
  • icXML/icXML-devel/src/icxmlc/XMLNamespaceResolver.c

    r3103 r3563  
    77/*
    88 * @author Nigel Medforth, nigelm -at- interational-characters.com
    9  * @version $Id: XMLNamespaceResolver.c 299 2013-04-27 21:42:40Z nigelm $
     9 * @version $Id: XMLNamespaceResolver.c 388 2013-10-29 21:25:27Z nigelm $
    1010 *
    1111 */
     
    2525IDISA_ALWAYS_INLINE
    2626gid_t
    27 XMLNamespaceResolver::bindNamespace(const XMLSymbol & symbol, const XMLCh * uri, const XMLSize_t length, const bool isXMLV1_1, bool & speculatedCorrectly, bool & bindingModifiesNamespaceContext, XMLErrs::Codes & bindingError)
     27XMLNamespaceResolver::bindNamespace(const XMLSymbol & symbol, const XMLCh * uri, const XMLSize_t length, const bool isXMLV1_1, bool & speculatedCorrectly)
    2828{
    2929        // Get the prefix id of the local part of this symbol name, e.g. the prefix id of "ogc" if the symbol is "xmlns:ogc"
    3030        // or fEmptyNamespaceId if the symbol is "xmlns"
    3131
    32     const static XMLErrs::Codes BINDING_ERRORS[4] = { XMLErrs::NoError, XMLErrs::NoUseOfxmlnsURI, XMLErrs::PrefixXMLNotMatchXMLURI, XMLErrs::XMLURINotMatchXMLPrefix };
    33 
    3432    const gid_t prefixId = symbol.getLocalPartId();
    3533
    36     gid_t linkId, uriId;
    37     resolveUri(uri, length, prefixId, linkId, uriId);
    38 
    39 
    40     bindingError = XMLErrs::NoError;
     34    DEBUG_NAMESPACE_MESSAGE("prefixId=" << prefixId)
     35
     36    gid_t uriId = resolveUri(uri, length, prefixId);
     37
     38    DEBUG_NAMESPACE_MESSAGE("uriId=" << uriId)
     39
    4140    // test if this prefix/uri pair is an error
    4241    if (unlikely(uriId == XMLNamespaceResolver::fEmptyUriId))
     
    5756            if (unlikely(prefixId != XMLNamespaceResolver::fEmptyUriId))
    5857            {
    59                 bindingError = XMLErrs::NoEmptyStrNamespace;
     58                throw XMLErrs::NoEmptyStrNamespace;
    6059            }
    6160        }
     
    6463    {
    6564        // is the XML URI being bound to some prefix other than "xml" or vice versa?
    66         const bool xmlBindingError = (prefixId == fXMLUriId) ^ (uriId == fXMLUriId);
    67         if (unlikely(xmlBindingError))
    68         {
    69             bindingError = BINDING_ERRORS[2 | (uriId == fXMLUriId)];
    70         }
    71         else
    72         {
    73             // is the XMLNS URI being bound to some prefix?
    74             bindingError = BINDING_ERRORS[(uriId == fXMLNSUriId)];
    75         }
    76     }
    77 
    78     if (unlikely(bindingError != XMLErrs::NoError))
    79     {
    80         return XMLNamespaceResolver::fUnknownUriId;
    81     }
    82 
    83     int namespaceId = resolveNamespaceId(prefixId);
     65        if (unlikely((prefixId == fXMLUriId) ^ (uriId == fXMLUriId)))
     66        {
     67            throw (uriId == fXMLUriId) ? XMLErrs::XMLURINotMatchXMLPrefix : XMLErrs::PrefixXMLNotMatchXMLURI;
     68        }       
     69        else if (unlikely(uriId == fXMLNSUriId)) // was the XMLNS URI bound to some prefix?
     70        {           
     71            throw XMLErrs::NoUseOfxmlnsURI;
     72        }
     73    }
     74
     75    const int namespaceId = resolveNamespaceId(prefixId);
     76
     77    DEBUG_NAMESPACE_MESSAGE("namespaceId=" << namespaceId)
     78
    8479    if (unlikely(namespaceId == -1))
    8580        {
    8681                // both the prefixId and the uriId exist, but they are not mapped to one another.
    87         mapPrefixToUri(prefixId, linkId, uriId);
     82        mapPrefixToUri(prefixId, uriId);
    8883
    8984        // since we speculated that the prefixId == globalUriId, if we find that this is not
    9085                // true, then we have to re-resolve everything regarding this element.
    9186        speculatedCorrectly &= (prefixId == uriId);
    92         bindingModifiesNamespaceContext = 1;
    93         }
    94     else
    95     {
    96         const gid_t priorUriId = getNamespaceUriId(namespaceId);
    97         if (likely(priorUriId != uriId))
    98         {
    99             remapPrefixToUri(prefixId, linkId, uriId);
     87        }
     88    else
     89    {
     90        const gid_t storedUriId = getNamespaceUriId(namespaceId);
     91
     92        DEBUG_NAMESPACE_MESSAGE("storedUriId=" << storedUriId)
     93
     94        if (likely(storedUriId != uriId))
     95        {
     96            remapPrefixToUri(prefixId, uriId);
    10097            speculatedCorrectly = 0;
    101             bindingModifiesNamespaceContext = 1;
    10298        }
    10399    }
     
    112108{
    113109    bool unknown = 0;
    114     return resolveUriId(symbol, isAttribute, unknown);
    115 }
    116 
    117 /// -----------------------------------------------------------------------------------------------
    118 
    119 IDISA_ALWAYS_INLINE
    120 gid_t
    121 XMLNamespaceResolver::resolveUriId(const XMLSymbol & symbol, const bool isAttribute, bool & unknown) const
     110    return resolveUriId(symbol, isAttribute, false, unknown);
     111}
     112
     113/// -----------------------------------------------------------------------------------------------
     114
     115IDISA_ALWAYS_INLINE
     116gid_t
     117XMLNamespaceResolver::resolveUriId(const XMLSymbol & symbol, const bool isAttribute, const bool misspeculated, bool & unknown) const
    122118{   
    123119    if (isAttribute && !symbol.isQualified())
     
    125121        return fEmptyUriId;
    126122        }
    127     return resolveUriId(symbol.getPrefixId(), symbol.getPrefixId(), unknown);
     123    return resolveUriId(symbol.getPrefixId(), (isAttribute && likely(!misspeculated) ? symbol.getPrefixId() : fUnknownUriId), unknown);
    128124}
    129125
     
    150146                if (likely(namespaceId != -1))
    151147                {
    152                         uriId = fNamespaceToUriBindingTable[namespaceId];
    153             unknown |= (uriId == XMLNamespaceResolver::fUnknownUriId);
     148            uriId = getNamespaceUriId(namespaceId);
     149            unknown = (uriId == XMLNamespaceResolver::fUnknownUriId);
    154150                }
    155151                else
    156152                {
    157             uriId = prefixId;
    158153                        unknown = true;
    159154                }
     
    175170        XMLSize_t length = XMLStringU::stringLen(uri);
    176171
    177     gid_t uriId = fUriPool.find(uri, length);
    178 
    179     if (unlikely(uriId == XMLNamespaceResolver::fUnknownUriId))
    180         {
    181                 XMLNamespaceResolver * self = const_cast<XMLNamespaceResolver*>(this);
    182 
    183                 // no, it was already used; claim the next unused uri id.
    184                 self->fNextUnreservedUriId = max(fNextUnreservedUriId, fNextUnreservedPrefixId);
    185         uriId = self->fNextUnreservedUriId++;
    186         self->fGlobalUriPool->addOrFind(uriId, uri, length, self->fUriPool);
    187         }
    188 
    189     return fUriPool[uriId].getId();
     172    const gid_t linkId = fUriPool.find(uri, length);
     173
     174    gid_t uriId;
     175
     176    if (unlikely(linkId == XMLNamespaceResolver::fUnknownUriId))
     177        {
     178        XMLNamespaceResolver * const self = const_cast<XMLNamespaceResolver*>(this);
     179        // no, it was already used; claim the next unused link id.
     180        uriId = self->fUriPool.add(max<size_t>(fPrefixCount, fUriPool.count()), uri, length, self->fGlobalUriPool);
     181        }
     182    else
     183    {
     184        #ifdef PRINT_DEBUG_MESSAGE
     185        assert (linkId < fUriPool.count());
     186        assert (XMLString::compareString(fUriPool[linkId].fKey, uri) == 0);
     187        #endif
     188        uriId = fUriPool[linkId].getId();
     189    }
     190
     191    return uriId;
    190192}
    191193
     
    311313    }
    312314
    313         fNextUnreservedPrefixId = max(fNextUnreservedPrefixId, fNextUnreservedUriId);
    314     const gid_t prefixId = fNextUnreservedPrefixId++;
     315    const gid_t prefixId = max<size_t>(fPrefixCount, fUriPool.count());
    315316
    316317        if (unlikely(fPrefixToNamespaceBindingTable.setCapacity() <= prefixId))
     
    347348
    348349IDISA_ALWAYS_INLINE
    349 void
    350 XMLNamespaceResolver::resolveUri(const XMLCh * uri, const XMLSize_t length, const gid_t preferredUriId, gid_t & linkId, gid_t & uriId)
    351 {
    352     linkId = fUriPool.find(uri, length);
    353 
    354     if (unlikely(linkId == -1))
    355         {
    356         linkId = preferredUriId;
     350gid_t
     351XMLNamespaceResolver::resolveUri(const XMLCh * uri, const XMLSize_t length, const gid_t prefixId)
     352{   
     353    gid_t linkId = fUriPool.find(uri, length);
     354    if (unlikely(linkId == XMLNamespaceResolver::fUnknownUriId))
     355        {
     356        DEBUG_MESSAGE(" -- adding new uriId")
     357        linkId = prefixId;
     358        if (unlikely(prefixId > fUriPool.capacity()))
     359        {
     360            fUriPool.resizeToFit(prefixId);
     361        }
    357362                // is the reserved uri slot for this prefix still free?
    358         if (unlikely(fUriPool[preferredUriId].getKey() != NULL))
     363        else if (unlikely(fUriPool[prefixId].getKey() != NULL))
    359364                {
    360365                        // no, it was already used; claim the next unused uri id.
    361                         fNextUnreservedUriId = max(fNextUnreservedUriId, fNextUnreservedPrefixId);
    362             linkId = fNextUnreservedUriId++;
     366            linkId = fUriPool.count();
    363367                }
    364368
    365         uriId = fGlobalUriPool->addOrFind(linkId, uri, length, fUriPool);
    366         }
    367     else
    368     {
    369         uriId = fUriPool[linkId].getId();
    370     }
    371 }
    372 
    373 /// -----------------------------------------------------------------------------------------------
    374 
    375 IDISA_ALWAYS_INLINE
    376 gid_t
    377 XMLNamespaceResolver::mapPrefixToUri(const gid_t prefixId, const gid_t linkId, const gid_t uriId)
     369        return fUriPool.add(linkId, uri, length, fGlobalUriPool);
     370        }
     371    else
     372    {
     373        return fUriPool[linkId].getId();
     374    }
     375}
     376
     377/// -----------------------------------------------------------------------------------------------
     378
     379IDISA_ALWAYS_INLINE
     380void
     381XMLNamespaceResolver::mapPrefixToUri(const gid_t prefixId, const gid_t uriId)
    378382{
    379383
    380384    // both the prefixId and the uriId exist, but they are not mapped to one another.
    381     const gid_t namespaceId = bindPrefixToUri(prefixId, linkId, uriId);
     385    const gid_t namespaceId = bindPrefixToUri(prefixId, uriId);
    382386
    383387    // add the new namespace to the namespace 'stack'
     
    391395
    392396IDISA_ALWAYS_INLINE
    393 gid_t
    394 XMLNamespaceResolver::remapPrefixToUri(const gid_t prefixId, const gid_t linkId, const gid_t uriId)
    395 {
    396     const int namespaceId = bindPrefixToUri(prefixId, linkId, uriId);
     397void
     398XMLNamespaceResolver::remapPrefixToUri(const gid_t prefixId, const gid_t uriId)
     399{
     400    const int namespaceId = bindPrefixToUri(prefixId, uriId);
    397401
    398402    BindingSet modified = (fCurrentlyVisibleNamespaces & fPrefixToNamespaceBindingTable[prefixId]);
     
    404408    // currently visible namespaces
    405409    fCurrentlyVisibleNamespaces ^= modified;
    406 
    407     return namespaceId;
    408 }
    409 
    410 /// -----------------------------------------------------------------------------------------------
    411 
    412 IDISA_ALWAYS_INLINE
    413 gid_t
    414 XMLNamespaceResolver::bindPrefixToUri(const gid_t prefixId, const gid_t linkId, const gid_t uriId)
     410}
     411
     412/// -----------------------------------------------------------------------------------------------
     413
     414IDISA_ALWAYS_INLINE
     415gid_t
     416XMLNamespaceResolver::bindPrefixToUri(const gid_t prefixId, const gid_t uriId)
    415417{
    416418    gid_t namespaceId = 0;
     
    430432                        namespaceId = namespaceItr.pos();
    431433
     434            DEBUG_NAMESPACE_MESSAGE(" --- found namespace mapping! " << namespaceId)
     435
    432436                        goto FOUND_NAMESPACE_MAPPING;
    433437                }
     
    435439
    436440        namespaceId = fNextNamespaceId++;
     441
     442    DEBUG_NAMESPACE_MESSAGE(" --- created new namespace mapping! " << namespaceId)
    437443
    438444    if (unlikely(fCurrentlyVisibleNamespaces.capacity() <= namespaceId))
     
    443449        fNamespaceToUriBindingTable.expand(namespaceId);
    444450        fNamespaceToPrefixBindingTable.expand(namespaceId);
     451        fPrefixToNamespaceBindingTable.increaseBitCapacity(namespaceId);
    445452                fLocallyModifiedNamespaces.increaseBitCapacity(namespaceId);
    446453                fDistinctContextSet.increaseBitCapacity(namespaceId);
     
    451458    // TODO: are declaring (or redeclaring) a namespace binding? or are we undeclaring it?
    452459
    453         // map this prefix to the namespace
     460    // map this prefix to the namespace and the URI back to the namespace
     461    assert (fPrefixToNamespaceBindingTable.setCapacity() > prefixId);
     462    assert (fPrefixToNamespaceBindingTable.bitCapacity() > namespaceId);
     463    assert (fNamespaceToPrefixBindingTable.capacity() > namespaceId);
     464    assert (fNamespaceToUriBindingTable.capacity() > namespaceId);
     465
    454466    fPrefixToNamespaceBindingTable[prefixId] += namespaceId;
    455     fNamespaceToPrefixBindingTable[namespaceId] = prefixId;
    456     // and the URI back to the namespace
     467    fNamespaceToPrefixBindingTable[namespaceId] = prefixId;   
    457468    fNamespaceToUriBindingTable[namespaceId] = uriId;
    458469
     
    484495)
    485496{
     497    DEBUG_MESSAGE("addPredefinedPrefix(" << id << ',' << prefix << ',' << uri << ')')
     498
     499
    486500        XMLPrefixEntry * entry = &fPrefixList[id];
    487501        // QUESTION: does storing the prefixes in the string pool help or hinder? we can just point to
     
    493507
    494508        // create the namespace entry and add it
    495     const gid_t uriId = fGlobalUriPool->addOrFind(id, uri, uriLength, fUriPool);
    496 
    497         assert (id == uriId);
    498 
    499     mapPrefixToUri(id, id, id);
     509    const gid_t uriId = fUriPool.add(id, uri, uriLength, fGlobalUriPool);
     510
     511    assert (id == uriId);
     512
     513    mapPrefixToUri(id, id);
    500514}
    501515
     
    504518/// -----------------------------------------------------------------------------------------------
    505519
    506 IDISA_ALWAYS_INLINE
    507 gid_t
    508 XMLNamespaceResolver::finalizeScope(const bool namespaceContextModified)
    509 {
    510     if (unlikely(namespaceContextModified))
    511     {
    512         for (size_t index = 0; index < fDistinctContextCount; index++)
    513         {
    514             if (fDistinctContextSet[index] == fCurrentlyVisibleNamespaces)
    515             {
    516                 fCurrentContextId = index;
     520void XMLNamespaceResolver::enterScope()
     521{
     522    fScope++;
     523    #ifdef ALLOW_NAMESPACE_SCOPE_SPECULATION
     524    const binding_t * locallyModified = fLocallyModifiedNamespaces.get(fCurrentScope);
     525    fSpeculatedNamespaces = locallyModified;
     526    fCurrentlyVisibleNamespaces ^= locallyModified;
     527    #endif
     528    fLocallyModifiedNamespaces[fScope] = 0;
     529}
     530
     531gid_t XMLNamespaceResolver::finalizeScope(const bool isEmpty, const bool containedXmlnsAttribute)
     532{
     533    size_t contextId;
     534    if (unlikely(containedXmlnsAttribute))
     535    {
     536        for (contextId = 0; contextId < fDistinctContextCount; contextId++)
     537        {
     538            if (fDistinctContextSet[contextId] == fCurrentlyVisibleNamespaces)
     539            {               
    517540                goto FoundExistingContextId;
    518541            }
     
    523546            fDistinctContextSet.increaseSetCapacity(fDistinctContextSet.setCapacity());
    524547        }
    525 
    526         fCurrentContextId = fDistinctContextCount++;
    527         fDistinctContextSet.set(fCurrentContextId, fCurrentlyVisibleNamespaces);
     548        contextId = fDistinctContextCount++;
     549        fDistinctContextSet.set(contextId, fCurrentlyVisibleNamespaces);
     550    }
     551    else
     552    {
     553        contextId = fCurrentContextId;
    528554    }
    529555
    530556FoundExistingContextId:
    531     fContextIdStack[fScope] = fCurrentContextId;
    532         return fCurrentContextId;
    533 }
     557
     558    if (isEmpty)
     559    {
     560        if (unlikely(containedXmlnsAttribute))
     561        {
     562            // if this empty tag did not contain any xmlns attributes, then it's impossible for
     563            // it to have modified the visible namespaces.
     564            fCurrentlyVisibleNamespaces ^= fLocallyModifiedNamespaces.get(fScope);           
     565        }
     566        fScope--;
     567    }
     568    else
     569    {
     570        fCurrentContextId = contextId;
     571        fContextIdStack[fScope] = contextId;
     572    }
     573    return contextId;
     574}
     575
     576gid_t XMLNamespaceResolver::leaveScope(bool & namespaceContextChange)
     577{
     578    fCurrentlyVisibleNamespaces ^= fLocallyModifiedNamespaces.get(fScope--);
     579    const gid_t contextId = fContextIdStack[fScope];
     580    namespaceContextChange = (contextId != fCurrentContextId);
     581    fCurrentContextId = contextId;
     582    return contextId;
     583}
     584
    534585
    535586/// -----------------------------------------------------------------------------------------------
     
    537588IDISA_ALWAYS_INLINE
    538589BindingSetIterator XMLNamespaceResolver::getNamespaceIterator(const gid_t contextId) const
    539 {
     590{   
    540591    return BindingSetIterator(fDistinctContextSet[contextId]);
    541592}
     
    546597MaskedBindingSetIterator XMLNamespaceResolver::getNamespaceIterator(const gid_t contextId0, const gid_t contextId1) const
    547598{
    548     return MaskedBindingSetIterator(fDistinctContextSet[contextId0], fDistinctContextSet[contextId1]);
     599    return MaskedBindingSetIterator(fDistinctContextSet[contextId0], fDistinctContextSet[contextId1], true);
     600}
     601
     602/// -----------------------------------------------------------------------------------------------
     603
     604IDISA_ALWAYS_INLINE
     605gid_t
     606XMLNamespaceResolver::getSchemaNamespaceId()
     607{
     608    if (unlikely(fSchemaNamespaceId == XMLNamespaceResolver::fUnknownUriId))
     609    {
     610        fSchemaNamespaceId = fGlobalUriPool->addOrFind(SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
     611    }
     612    return fSchemaNamespaceId;
    549613}
    550614
     
    573637XMLNamespaceResolver::getUriForNamespaceId(const gid_t namespaceId) const
    574638{
    575     return (*this)[fNamespaceToUriBindingTable[namespaceId]];
     639    return getUriForId(fNamespaceToUriBindingTable[namespaceId]);
    576640}
    577641
     
    580644IDISA_ALWAYS_INLINE
    581645bool
    582 XMLNamespaceResolver::isPrefixVisible(const XMLCh * prefix, const gid_t contextId)
     646XMLNamespaceResolver::isPrefixVisible(const XMLCh * prefix, const gid_t contextId) const
    583647{
    584648    int colonPos;
     
    591655IDISA_ALWAYS_INLINE
    592656bool
    593 XMLNamespaceResolver::isPrefixVisible(const gid_t prefixId)
     657XMLNamespaceResolver::isPrefixVisible(const gid_t prefixId) const
    594658{
    595659    if (unlikely(prefixId == XMLNamespaceResolver::fUnknownUriId))
    596660    {
    597         return 0;
    598     }
    599     const gid_t namespaceId = fPrefixToNamespaceBindingTable[prefixId].first(fCurrentlyVisibleNamespaces);
     661        return false;
     662    }   
     663    const int namespaceId = resolveNamespaceId(prefixId);
     664
    600665    if (unlikely(namespaceId == -1))
    601666    {
     
    604669    else
    605670    {
    606         return fNamespaceToUriBindingTable[namespaceId] != XMLNamespaceResolver::fUnknownUriId;
     671        return (getNamespaceUriId(namespaceId) != XMLNamespaceResolver::fUnknownUriId);
    607672    }
    608673}
     
    612677IDISA_ALWAYS_INLINE
    613678bool
    614 XMLNamespaceResolver::isPrefixVisible(const gid_t prefixId, const gid_t contextId)
     679XMLNamespaceResolver::isPrefixVisible(const gid_t prefixId, const gid_t contextId) const
    615680{
    616681    if (unlikely(prefixId == XMLNamespaceResolver::fUnknownUriId))
    617682    {
    618         return 0;
     683        return false;
    619684    }
    620685
     
    626691    else
    627692    {
    628         return fNamespaceToUriBindingTable[namespaceId] != XMLNamespaceResolver::fUnknownUriId;
     693        return (getNamespaceUriId(namespaceId) != XMLNamespaceResolver::fUnknownUriId);
    629694    }
    630695}
     
    672737IDISA_ALWAYS_INLINE
    673738const XMLCh *
    674 XMLNamespaceResolver::getUriForQName(const XMLCh * prefix, const gid_t contextId, int & colonPos)
     739XMLNamespaceResolver::getUriForQName(const XMLCh * prefix, const gid_t contextId, int & colonPos) const
    675740{
    676741    gid_t uriId = getUriIdForQName(prefix, contextId, colonPos);
     
    683748IDISA_ALWAYS_INLINE
    684749const XMLCh *
    685 XMLNamespaceResolver::getUriForPrefix(const XMLCh * prefix, const gid_t contextId)
     750XMLNamespaceResolver::getUriForPrefix(const XMLCh * prefix, const gid_t contextId) const
    686751{
    687752    int colonPos;
     
    693758IDISA_ALWAYS_INLINE
    694759const XMLCh *
    695 XMLNamespaceResolver::getUriForPrefix(const gid_t prefixId, const gid_t contextId)
     760XMLNamespaceResolver::getUriForPrefix(const gid_t prefixId, const gid_t contextId) const
    696761{   
    697762    return getUriForId(getUriIdForPrefix(prefixId, contextId));
     
    708773                const XMLCh * uri;
    709774
    710         for (gid_t uriId = 0; uriId < resolver->fNextUnreservedUriId; uriId++)
     775        for (gid_t uriId = 0; uriId < resolver->getUriCount(); uriId++)
    711776                {
    712777                        if ((uri = (*resolver)[uriId]) != 0)
  • icXML/icXML-devel/src/icxmlc/XMLNamespaceResolver.hpp

    r3103 r3563  
    77/*
    88 * @author Nigel Medforth, nigelm -at- interational-characters.com
    9  * @version $Id: XMLNamespaceResolver.hpp 289 2013-04-12 01:21:31Z nigelm $
     9 * @version $Id: XMLNamespaceResolver.hpp 388 2013-10-29 21:25:27Z nigelm $
    1010 *
    1111 */
     
    2121#include <xercesc/util/XMLUni.hpp>
    2222#include <icxercesc/util/QName.hpp>
     23#include <xercesc/util/StringPool.hpp>
    2324#include <icxmlc/XMLNamespaceBindingSet.hpp>
    2425#include <icxmlc/XMLStringHash.hpp>
     
    121122        // TODO: would adding SchemaSymbols::fgURI_SCHEMAFORSCHEMA as a predefined uri help?
    122123
    123                 XMLNamespaceResolver(XMLNamespaceResolver * parent, MemoryManager* manager)
    124         : fNextUnreservedPrefixId(fPredefinedCount)
    125         , fNextUnreservedUriId(fPredefinedCount)
     124        XMLNamespaceResolver(XMLStringPool * globalUriPool, MemoryManager* manager)
     125        : fScope(0)
    126126        , fNextNamespaceId(0)
    127127        , fPrefixCount(fPredefinedCount)
    128         , fScope(0)
     128        , fCurrentContextId(0)
     129        , fDistinctContextCount(1)
     130        , fGlobalUriPool(globalUriPool)
     131        , fSchemaNamespaceId(fUnknownUriId)
    129132        , fUriPool(manager)
    130         , fDistinctContextCount(0)
    131         , fCurrentContextId(0)
    132         , fGlobalUriPool(parent ? parent->fGlobalUriPool : new XMLGlobalNamespaceTable(manager))
    133         , fAdoptedGlobalUriPool(parent != 0)
    134         , fPrefixPool(manager)
     133        , fPrefixPool(manager)       
    135134                {
    136135                        addPredefinedPrefix(fEmptyUriId, XMLUni::fgZeroLenString, 0, XMLUni::fgZeroLenString, 0);
    137136                        addPredefinedPrefix(fXMLUriId, XMLUni::fgXMLString, 3, XMLUni::fgXMLURIName, 36);
    138137                        addPredefinedPrefix(fXMLNSUriId, XMLUni::fgXMLNSString, 5, XMLUni::fgXMLNSURIName, 29);
    139                         addPredefinedPrefix(fSchemaInstanceUriId, SchemaSymbols::fgXSI, 3, SchemaSymbols::fgURI_XSI, 41);
    140                         fCurrentlyVisibleNamespaces += fEmptyUriId;
    141                         fCurrentlyVisibleNamespaces += fXMLUriId;
    142                         fCurrentlyVisibleNamespaces += fXMLNSUriId;
    143             finalizeScope(true);
     138                        addPredefinedPrefix(fSchemaInstanceUriId, SchemaSymbols::fgXSI, 3, SchemaSymbols::fgURI_XSI, 41);           
     139
     140            // mark the 'always visible' namespaces
     141            fCurrentlyVisibleNamespaces.set((1 << fEmptyUriId) | (1 << fXMLUriId) | (1 << fXMLNSUriId));
     142            // store this context set permanently
     143            fDistinctContextSet.set(0, fCurrentlyVisibleNamespaces);
    144144                }
    145145
    146146                ~XMLNamespaceResolver()
    147147                {
    148                         if (!fAdoptedGlobalUriPool)
    149                         {
    150                                 delete fGlobalUriPool;
    151                         }
    152                 }
    153 
    154         gid_t bindNamespace(const XMLSymbol & symbol, const XMLCh * uri, const XMLSize_t length, const bool isXMLV1_1, bool & speculatedCorrectly, bool & modifiesNamespaceContext, XMLErrs::Codes & bindingError);
    155 
    156         void setEmptyUriId(const gid_t uriId);
     148
     149                }
     150
     151        gid_t bindNamespace(const XMLSymbol & symbol, const XMLCh * uri, const XMLSize_t length, const bool isXMLV1_1, bool & speculatedCorrectly);
    157152
    158153        gid_t resolveUriId(const XMLSymbol & symbol, const bool isAttribute) const;
    159154
    160         gid_t resolveUriId(const XMLSymbol & symbol, const bool isAttribute, bool & unknown) const;
     155        gid_t resolveUriId(const XMLSymbol & symbol, const bool isAttribute, const bool misspeculated, bool & unknown) const;
    161156
    162157        gid_t resolveUriId(const XMLCh * uri) const;
     
    171166        void setMaxScope(const size_t maxScope)
    172167        {
     168            DEBUG_NAMESPACE_MESSAGE("XMLNamespaceResolver::setMaxScope(" << maxScope << ')')
    173169            fLocallyModifiedNamespaces.increaseSetCapacity(maxScope);
    174             fContextIdStack.resizeToFit(fScope, maxScope);
    175         }
    176 
    177                 IDISA_ALWAYS_INLINE
    178                 void enterScope()
    179                 {
    180             fScope++;
    181             #ifdef ALLOW_NAMESPACE_SCOPE_SPECULATION
    182             const binding_t * locallyModified = fLocallyModifiedNamespaces.get(fCurrentScope);
    183             fSpeculatedNamespaces = locallyModified;
    184             fCurrentlyVisibleNamespaces ^= locallyModified;
    185             #endif
    186             fLocallyModifiedNamespaces[fScope] = 0;
    187                 }
    188 
    189         gid_t finalizeScope(const bool namespaceContextModified);
    190 
    191                 IDISA_ALWAYS_INLINE
    192         gid_t leaveScope(bool & namespaceContextChange)
    193                 {           
    194             assert ((ssize_t)fScope != -1);
    195             fCurrentlyVisibleNamespaces ^= fLocallyModifiedNamespaces.get(fScope--);
    196             const gid_t contextId = fContextIdStack[fScope];           
    197             namespaceContextChange = (contextId != fCurrentContextId);
    198             fCurrentContextId = contextId;
    199             return contextId;
    200                 }
     170            fContextIdStack.resizeToFit(fScope, maxScope + 1);
     171        }
     172
     173        IDISA_ALWAYS_INLINE
     174        gid_t getSchemaNamespaceId();
     175
     176                IDISA_ALWAYS_INLINE
     177        void enterScope();
     178
     179        IDISA_ALWAYS_INLINE
     180        gid_t finalizeScope(const bool isEmpty, const bool containedXmlnsAttribute);
     181
     182                IDISA_ALWAYS_INLINE
     183        gid_t leaveScope(bool & namespaceContextChange);
    201184
    202185                IDISA_ALWAYS_INLINE
     
    224207        const XMLCh * getUriForNamespaceId(const gid_t namespaceId) const;
    225208
    226         bool isPrefixVisible(const XMLCh * prefix, const gid_t contextId);
    227 
    228         bool isPrefixVisible(const gid_t prefixId);
    229 
    230         bool isPrefixVisible(const gid_t prefixId, const gid_t contextId);
    231 
    232         const XMLCh * getUriForQName(const XMLCh * prefix, const gid_t contextId, int & colonPos);
    233 
    234         const XMLCh * getUriForPrefix(const XMLCh * prefix, const gid_t contextId);
    235 
    236         const XMLCh * getUriForPrefix(const gid_t prefixId, const gid_t contextId);
     209        bool isPrefixVisible(const XMLCh * prefix, const gid_t contextId) const;
     210
     211        bool isPrefixVisible(const gid_t prefixId) const;
     212
     213        bool isPrefixVisible(const gid_t prefixId, const gid_t contextId) const;
     214
     215        const XMLCh * getUriForQName(const XMLCh * prefix, const gid_t contextId, int & colonPos) const;
     216
     217        const XMLCh * getUriForPrefix(const XMLCh * prefix, const gid_t contextId) const;
     218
     219        const XMLCh * getUriForPrefix(const gid_t prefixId, const gid_t contextId) const;
    237220
    238221        gid_t getUriIdForQName(const XMLCh * prefix, const gid_t contextId, int & colonPos) const;
     
    248231        gid_t addOrFindPrefixId(const XMLCh * qName, const XMLSize_t length, int & colon);
    249232
     233
     234
    250235                const XMLCh * addOrFindPrefix(const XMLCh * qName);
    251236
     
    253238        const XMLCh * operator[](const gid_t uriId) const
    254239                {
    255             assert (uriId != fUnknownUriId);
    256             const XMLNamespaceEntry & entry = (*fGlobalUriPool)[uriId];
    257             return entry.getKey();
     240            return fGlobalUriPool->getValueForId(uriId);
    258241                }
    259242
     
    261244        const XMLCh * getUriForId(const gid_t uriId, const bool isAttribute = 0) const
    262245                {
    263                         if (unlikely((isAttribute && (uriId == fEmptyUriId)) || (uriId == fUnknownUriId)))
     246            if (unlikely((isAttribute && (uriId == fEmptyUriId)) || (uriId == (gid_t)(fUnknownUriId))))
    264247                        {
    265248                                return NULL;
     
    273256                }
    274257
    275                 IDISA_ALWAYS_INLINE
    276                 size_t getUriCount() const
    277                 {
    278                         return fGlobalUriPool->count();
    279                 }
     258        inline size_t getUriCount() const
     259                {
     260            return fGlobalUriPool->getStringCount();
     261                }
     262
     263        inline gid_t getCurrentContextId() const
     264        {
     265            return fCurrentContextId;
     266        }
    280267
    281268                IDISA_ALWAYS_INLINE
     
    294281                const XMLPrefixEntry * addOrFindPrefix(const XMLCh * prefix, const int length);
    295282
    296         void resolveUri(const XMLCh * uri, const XMLSize_t length, const gid_t preferredUriId, gid_t & linkId, gid_t & uriId);
    297 
    298         gid_t mapPrefixToUri(const gid_t prefixId, const gid_t linkId, const gid_t uriId);
    299 
    300         gid_t remapPrefixToUri(const gid_t prefixId, const gid_t linkId, const gid_t uriId);
    301 
    302         gid_t bindPrefixToUri(const gid_t prefixId, const gid_t linkId, const gid_t uriId);
     283        gid_t resolveUri(const XMLCh * uri, const XMLSize_t length, const gid_t preferredUriId);
     284
     285        void mapPrefixToUri(const gid_t prefixId, const gid_t uriId);
     286
     287        void remapPrefixToUri(const gid_t prefixId, const gid_t uriId);
     288
     289        gid_t bindPrefixToUri(const gid_t prefixId, const gid_t uriId);
    303290
    304291                IDISA_ALWAYS_INLINE
    305292        int resolveNamespaceId(const gid_t prefixId) const
    306293                {
    307                         return fCurrentlyVisibleNamespaces.first(fPrefixToNamespaceBindingTable[prefixId]);
     294            return fCurrentlyVisibleNamespaces.first(fPrefixToNamespaceBindingTable[prefixId]);
    308295                }
    309296
     
    312299        private:
    313300
    314         size_t                                                                                                  fScope;
    315         gid_t                                                                                                   fNextUnreservedUriId;
    316         size_t                                                                                                  fDistinctContextCount;
    317         gid_t                                                                                                   fCurrentContextId;       
    318         gid_t                                                                                                   fNextUnreservedPrefixId;
     301        size_t                                                                                                  fScope;     
    319302        gid_t                                                                                                   fNextNamespaceId;
    320303        gid_t                                                                                                   fPrefixCount;
     304        gid_t                                                                                                   fCurrentContextId;
     305        size_t                                                                                                  fDistinctContextCount;
     306
     307        XMLStringPool * const                                   fGlobalUriPool;
     308
     309        gid_t                                                   fSchemaNamespaceId;
    321310
    322311        BindingSet                                                                                              fCurrentlyVisibleNamespaces;
     
    333322        DynamicArray<XMLPrefixEntry, sizeof(hash_t) * 8>                fPrefixList;
    334323        XMLNamespaceTable                                                                               fUriPool;
    335         BindingSets<INITIAL_MAX_SCOPE>                                                  fDistinctContextSet;
    336         XMLGlobalNamespaceTable * const                                                 fGlobalUriPool;
     324        BindingSets<INITIAL_MAX_SCOPE>                                                  fDistinctContextSet;       
    337325        StringPool<XMLCh, DEFAULT_PREFIX_POOL_SIZE>             fPrefixPool;
    338 
    339         const bool                                                                                              fAdoptedGlobalUriPool;
    340326};
    341327
  • icXML/icXML-devel/src/icxmlc/XMLNamespaceUriTable.hpp

    r3104 r3563  
    1212#include <icxmlc/XMLStringU.hpp>
    1313#include <xercesc/util/XMLUni.hpp>
     14#include <xercesc/util/StringPool.hpp>
    1415#include <icxmlc/XMLScanIterator.hpp>
    1516#include <icxercesc/validators/common/Grammar.hpp>
     
    7172                }
    7273
     74        inline ~XMLNamespaceEntry()
     75        {
     76
     77        }
     78
    7379        protected:
    7480
     
    8389class XMLNamespaceTable
    8490{
    85         friend class XMLGlobalNamespaceTable;
    86 
    8791        public:
    8892
    8993        XMLNamespaceTable(MemoryManager * manager)
    90         : fURIPool(manager)
    9194                {
    9295
     
    106109
    107110                IDISA_ALWAYS_INLINE
    108                 size_t count() const
     111        const size_t count() const
    109112                {
    110113                        return fHashTable.count();
    111114                }
    112115
    113         protected:
     116        IDISA_ALWAYS_INLINE
     117        const size_t capacity() const
     118        {
     119            return fHashTable.capacity();
     120        }
    114121
    115                 IDISA_ALWAYS_INLINE
    116         unsigned int add(const unsigned int localId, const unsigned int globalId, const XMLCh * uri, const size_t length)
    117                 {
    118             uri = fURIPool.insert(uri, length);
    119             XMLNamespaceEntry entry(globalId, uri, length);
    120                         return fHashTable.add(entry, localId);
    121                 }
     122        void resizeToFit(const size_t size)
     123        {
     124            fHashTable.resizeToFit(size);
     125        }
     126
     127        IDISA_ALWAYS_INLINE
     128        unsigned int add(const unsigned int localId, const XMLCh * uri, const size_t length, XMLStringPool * globalURIPool)
     129        {
     130            const unsigned int uriId = globalURIPool->addOrFind(uri);
     131            XMLNamespaceEntry entry(uriId, globalURIPool->getValueForId(uriId), length);
     132            fHashTable.add(entry, localId);
     133            return uriId;
     134        }
    122135
    123136        private:
    124137
    125138                HashTable<XMLNamespaceEntry, XMLCh, sizeof(hash_t) * 16, 1>                     fHashTable;
    126         StringPool<XMLCh, INITIAL_NAMESPACE_RESOLVER_STRING_POOL_SIZE>          fURIPool;
    127 };
    128 
    129 /// ---------------------------------------------------------------------------------------------------------
    130 
    131 class XMLGlobalNamespaceTable
    132 {
    133         public:
    134 
    135                 XMLGlobalNamespaceTable(MemoryManager * manager)
    136         : fURIPool(manager)
    137                 {
    138 
    139                 }
    140 
    141         ~XMLGlobalNamespaceTable()
    142         {
    143             DEBUG_MESSAGE("XMLGlobalNamespaceTable::~XMLGlobalNamespaceTable()");
    144         }
    145 
    146                 IDISA_ALWAYS_INLINE
    147         const XMLNamespaceEntry & operator[](const size_t id) const
    148                 {
    149                         return fHashTable[id];
    150                 }
    151 
    152                 IDISA_ALWAYS_INLINE
    153         unsigned int addOrFind(const unsigned int localId, const XMLCh * uri, const size_t length, XMLNamespaceTable & localTable)
    154         {
    155             size_t normLength;
    156             bool collapsedInteriorWhitespace;
    157             const XMLCh * normURI = normalizeWhitespace(uri, length, normLength, collapsedInteriorWhitespace);
    158 
    159 
    160             unsigned int globalId = fHashTable.find(normURI, normLength);
    161             if (globalId == -1)
    162             {
    163                 XMLNamespaceEntry entry(count(), fURIPool.insert(normURI, normLength), normLength);
    164                 globalId = fHashTable.add(entry);
    165             }
    166 
    167             if (collapsedInteriorWhitespace)
    168             {
    169                 Array<const XMLCh>::deallocate(normURI);
    170             }
    171 
    172             localTable.add(localId, globalId, uri, length);
    173                         return globalId;
    174                 }
    175 
    176                 IDISA_ALWAYS_INLINE
    177                 size_t count() const
    178                 {
    179                         return fHashTable.count();
    180                 }
    181 
    182 
    183 
    184 
    185         private:
    186 
    187         IDISA_ALWAYS_INLINE
    188         const XMLCh * normalizeWhitespace(const XMLCh * uri, const size_t length, size_t & normalizedLength, bool & collapsedInteriorWhitespace)
    189         {
    190 #if 0
    191             size_t start = 0;
    192             size_t end = length;
    193 
    194             while (unlikely(uri[start] == chSpace)) start++;
    195             while (unlikely(uri[end - 1] == chSpace)) end--;
    196 
    197             normalizedLength = end - start;
    198 
    199             collapsedInteriorWhitespace = 0;
    200 
    201             for (size_t pos = start; pos < end; pos++)
    202             {
    203                 // whats the first non-whitespace position?
    204                 if (unlikely(uri[pos] == chSpace && uri[pos + 1] == chSpace))
    205                 {
    206                     collapsedInteriorWhitespace = true;
    207                     break;
    208                 }
    209             }
    210 
    211             if (unlikely(collapsedInteriorWhitespace))
    212             {
    213                 XMLCh * normalizedUri = Array<XMLCh>::allocate(normalizedLength);
    214 
    215                 normalizedLength = 1;
    216 
    217                 for (size_t pos = start; pos < end; pos++)
    218                 {
    219                     // whats the first non-whitespace position?
    220                     if (unlikely(uri[pos] == chSpace))
    221                     {
    222                         normalizedUri[normalizedLength++] = chSpace;
    223                         while (unlikely(uri[pos + 1] == chSpace))
    224                         {
    225                             pos++;
    226                         }
    227                     }
    228                     normalizedUri[normalizedLength++] = uri[pos];
    229                 }
    230                 normalizedUri[normalizedLength] = chNull;
    231                 return normalizedUri;
    232             }
    233             else
    234             {
    235                 return &uri[start];
    236             }
    237 #endif
    238             normalizedLength = length;
    239             collapsedInteriorWhitespace = 0;
    240             return uri;
    241         }
    242 
    243 
    244         HashTable<XMLNamespaceEntry, XMLCh, sizeof(hash_t) * 16, 0>                     fHashTable;
    245         StringPool<XMLCh, INITIAL_NAMESPACE_RESOLVER_STRING_POOL_SIZE>          fURIPool;
    246139};
    247140
  • icXML/icXML-devel/src/icxmlc/XMLParallelTokenizer.hpp

    r3103 r3563  
    77/*
    88 * @author Nigel Medforth, nigelm -at- interational-characters.com
    9  * @version $Id: XMLParallelTokenizer.hpp 245 2013-01-17 01:31:50Z nigelm $
     9 * @version $Id: XMLParallelTokenizer.hpp 385 2013-10-22 21:21:29Z nigelm $
    1010 *
    1111 */
     
    1818#include <icxmlc/XMLConfig.hpp>
    1919
    20 #if BLOCK_SIZE == 128
    21 #else
    22         #error "XMLParallelTokenizer is not defined yet for this BLOCK_SIZE"
    23 #endif
    2420
    2521XERCES_CPP_NAMESPACE_BEGIN
     
    2824{
    2925                typedef scanword_t iterator_t;
    30                 enum { BITS_PER_ITERATOR = sizeof(iterator_t) * 8 };
     26
     27        enum
     28        {
     29            BITS_PER_ITERATOR = sizeof(iterator_t) * 8
     30        };
    3131
    3232        public:
     
    7474                void addTokens(XMLCh * src, iterator_t whitespace, iterator_t whitespace_carry);
    7575
    76                 template<size_t blocks>
     76        template<size_t BLOCKS>
    7777                IDISA_ALWAYS_INLINE
    7878                static iterator_t tokenize(const BytePack * input, const BytePack m1, const BytePack m2, const BytePack m3);
    7979
    80                 template<size_t blocks>
     80        template<size_t BLOCKS>
    8181                IDISA_ALWAYS_INLINE
    8282                static BytePack mask(const BytePack * input, const BytePack m1, const BytePack m2, const BytePack m3);
     
    102102        while (length >= BITS_PER_ITERATOR)
    103103        {
    104                 iterator_t whitespace = tokenize<sizeof(iterator_t)>(src, spmask, lfmask, htmask);
     104        iterator_t whitespace = tokenize<sizeof(iterator_t)>(src, spmask, lfmask, htmask);
    105105                addTokens((XMLCh*)src, whitespace, whitespaceCarry);
    106106                whitespaceCarry = whitespace >> (BITS_PER_ITERATOR - 1);
     
    113113                const iterator_t one = 1;
    114114                const iterator_t lengthMask = (one << length) - 1;
    115                 iterator_t whitespace = tokenize<sizeof(iterator_t)>(src, spmask, lfmask, htmask) | ~lengthMask;
     115        iterator_t whitespace = tokenize<sizeof(iterator_t)>(src, spmask, lfmask, htmask) | ~lengthMask;
    116116                addTokens((XMLCh*)src, whitespace, whitespaceCarry);
    117117        }
     
    135135        while (length >= BITS_PER_ITERATOR)
    136136        {
    137                 const iterator_t tuples =
    138                         tokenize<sizeof(iterator_t)>(src, eqmask, sqmask, dqmask);
    139                 const iterator_t whitespace =
    140                         tokenize<sizeof(iterator_t)>(src, spmask, lfmask, htmask) | tuples;
     137        const iterator_t tuples = tokenize<sizeof(iterator_t)>(src, eqmask, sqmask, dqmask);
     138        const iterator_t whitespace = tokenize<sizeof(iterator_t)>(src, spmask, lfmask, htmask) | tuples;
    141139
    142140                // validate that the tuple markers are in the correct order
     
    158156                const iterator_t one = 1;
    159157                const iterator_t lengthMask = (one << (length - 1)) - 1;
    160 
    161                 const iterator_t tuples =
    162                         tokenize<sizeof(iterator_t)>(src, eqmask, sqmask, dqmask) & lengthMask;
    163 
    164                 const iterator_t whitespace =
    165                         (tokenize<sizeof(iterator_t)>(src, spmask, lfmask, htmask) | tuples) | ~lengthMask;
     158        const iterator_t tuples = tokenize<sizeof(iterator_t)>(src, eqmask, sqmask, dqmask) & lengthMask;
     159        const iterator_t whitespace = (tokenize<sizeof(iterator_t)>(src, spmask, lfmask, htmask) | tuples) | ~lengthMask;
    166160
    167161                // validate that the tuple markers are in the correct order
     
    266260        const BytePack b = mask<1>(&input[0], m1, m2, m3);
    267261        const BytePack a = mask<1>(&input[1], m1, m2, m3);
    268         return hsimd128<16>::packss(a, b);
     262    return hsimd<16>::packss(a, b);
    269263}
    270264
     
    272266IDISA_ALWAYS_INLINE
    273267iterator_t
    274 XMLParallelTokenizer::tokenize<1>(const BytePack * input, const BytePack m1, const BytePack m2, const BytePack m3)
    275 {
    276         return hsimd<16>::signmask(mask<1>(&input[0], m1, m2, m3));
     268XMLParallelTokenizer::tokenize<BLOCK_SIZE / 128>(const BytePack * input, const BytePack m1, const BytePack m2, const BytePack m3)
     269{
     270    return static_cast<iterator_t>(hsimd<16>::signmask(mask<1>(&input[0], m1, m2, m3)));
    277271}
    278272
     
    280274IDISA_ALWAYS_INLINE
    281275iterator_t
    282 XMLParallelTokenizer::tokenize<2>(const BytePack * input, const BytePack m1, const BytePack m2, const BytePack m3)
    283 {
    284         return hsimd<8>::signmask(mask<2>(&input[0], m1, m2, m3));
    285 }
    286 
    287 template<size_t blocks>
     276XMLParallelTokenizer::tokenize<BLOCK_SIZE / 64>(const BytePack * input, const BytePack m1, const BytePack m2, const BytePack m3)
     277{
     278    return static_cast<iterator_t>(hsimd<8>::signmask(mask<2>(&input[0], m1, m2, m3)));
     279}
     280
     281template<size_t BLOCKS>
    288282IDISA_ALWAYS_INLINE
    289283iterator_t
    290284XMLParallelTokenizer::tokenize(const BytePack * input, const BytePack m1, const BytePack m2, const BytePack m3)
    291285{
    292         enum { half = (blocks / 2) };
    293 
    294         return tokenize<half>(&input[0], m1, m2, m3) | (tokenize<blocks - half>(&input[half], m1, m2, m3) << (half * 8));
     286    enum
     287    {
     288        BLOCKS_DIV_2 = (BLOCKS / 2)
     289        , SHIFT_OFFSET = (BLOCKS_DIV_2 * 8)
     290    };
     291
     292    return tokenize<BLOCKS_DIV_2>(&input[0], m1, m2, m3) | (tokenize<BLOCKS - BLOCKS_DIV_2>(input + BLOCKS_DIV_2, m1, m2, m3) << SHIFT_OFFSET);
    295293}
    296294
  • icXML/icXML-devel/src/icxmlc/XMLParser.hpp

    r3151 r3563  
    77/*
    88 * @author Nigel Medforth, nigelm -at- interational-characters.com
    9  * @version $Id: XMLParser.hpp 307 2013-05-08 23:02:44Z nigelm $
     9 * @version $Id: XMLParser.hpp 375 2013-09-22 22:19:15Z nigelm $
    1010 *
    1111 */
     
    3232#include <xercesc/validators/datatype/DatatypeValidator.hpp>
    3333#include <icxmlc/XMLConfig.hpp>
     34#include <PapiCounter.hpp>
    3435
    3536XERCES_CPP_NAMESPACE_BEGIN
     
    4950class XMLDocumentDisseminator;
    5051class XMLDocumentHandler;
     52class XMLStringPool;
     53class XMLScanner;
    5154
    5255/**
     
    6063    template<class ScannerType> friend class XMLWellFormednessParser;
    6164    template<class ScannerType> friend class XMLNamespaceParser;
    62     template<class ScannerType> friend class XMLGrammarValidator;
    63     friend class XMLDocumentDisseminator;
     65    template<class ScannerType> friend class XMLGrammarValidator;   
     66    template <class DocHandlerType, bool doPSVI> friend class XMLDocumentDisseminatorImpl;
     67    template <bool doPSVI> friend class SAX2DocumentDisseminatorImpl;
     68    template <bool doPSVI> friend class SAXDocumentDisseminatorImpl;
     69    friend class XSDDOMDocumentDisseminatorImpl;
    6470    friend class XMLReader;
     71    friend class XMLIdentityConstraintValidator;
     72    friend class XMLUTF8CharacterSetAdapter;
     73    friend class XMLUTF16CharacterSetAdapter;
    6574
    6675    public:
     
    93102    public:
    94103
    95         void getCurrentLineCol
    96         (
    97             XMLFileLoc                 &   line
    98             , XMLFileLoc               &   col
    99         ) const;
     104        void getLocator(XMLFileLoc & line, XMLFileLoc & col) const;
     105
     106        LineColumnPtrType calculateMarkupLocation(const LineColumnPtrType from, const LineColumnPtrType to, XMLFileLoc & line, XMLFileLoc & col);
     107
     108        virtual XMLScanner & getScanner() const = 0;
    100109
    101110    protected:
    102111
    103         XMLParser(MemoryManager * manager);
     112        XMLParser(XMLReader & reader, XMLStringPool * uriPool, MemoryManager * manager);
    104113
    105114        virtual ~XMLParser() = 0;
     
    111120        size_t                              fReferenceIdx;
    112121        DelimiterPtrType                    fStringEndPtr;
    113         size_t                              fUriIdx;
    114 
    115         size_t                              fContextIdx;
    116         size_t                              fDocumentContextIdx;
    117         size_t                              fDocumentObjectIdx;
     122
    118123        size_t                              fDocumentObjectCount;
    119124
    120125        size_t                              fScope;
     126        size_t                              fErrorDepth;
     127
    121128        size_t                              fElementIndex;
    122129        size_t                              fMarkupCount;
     
    125132        XMLSize_t                           fMaxAttributeCount;
    126133        bool                                fNoMore;
    127         bool                                fEndsWithPartialContent;
    128134        bool                                fInMarkup;
    129135        bool                                fInElement;
     
    137143        size_t                              fUriCount;
    138144
     145        bool                                fHasIdentityConstraints;
     146
    139147        XMLBuffer *                         fEntityContentBuffer;
    140148
     
    143151        SymbolArray                                                     fSymbolStream;       
    144152        SymbolUriArray                                          fUriStream;
    145         SymbolUriArray                                          fContextStream;       
     153        SymbolUriArray                                          fNamespaceContextStream;
    146154        ReferenceArray                      fReferenceStream;
     155
     156        XMLFileLoc &                        fLine;
     157        XMLFileLoc &                        fColumn;       
     158        LineColumnDiffStream                fLineColumnStream;
    147159
    148160        GidStack                                                        fGidStack;
     
    161173        const XMLCh *                       fCursorEndPtr;
    162174
    163         /// ------------------  ERROR HANDLING VARIABLES ---------------------- ///
    164 
    165 
    166 
    167 
    168 
     175        XMLNamespaceResolver                            fNamespaceResolver;
     176
     177        XMLReader &                         fReader;
     178
     179        #ifdef PAPI_EVENT_SET
     180        IPapiCounter *                      fPapiCounter;
     181        #endif
    169182};
    170183
     
    172185
    173186IDISA_ALWAYS_INLINE
    174 XMLParser::XMLParser(MemoryManager * manager)
    175     : fContentIdx(0)
    176     , fSymbolCount(0)
    177     , fReferenceCount(0)   
    178     , fStringCount(0)   
    179     , fDocumentContextIdx(0)
    180     , fDocumentObjectIdx(0)
    181     , fDocumentObjectCount(0)
    182     , fScope(0)
    183     , fMaxScope(0)
    184     , fMaxAttributeCount(0)   
    185     , fGidStack()
    186     , fElementIndex(-1)
    187     , fElement()
    188     , fChildren()
    189     , fNoMore(true)
    190     , fEndsWithPartialContent(false)
    191     , fInMarkup(0)
    192     , fElementCount(0)
    193     , fCharacterSetAdapter(0)
    194     , fEntityContentBuffer(0)
    195     , fInElement(0)
    196     , fContainsXsiTypeOrNil(0)
    197     , fContentStream()
    198     , fSymbolStream()
    199     , fReferenceStream()
    200     , fUriStream()
    201     , fContextStream()
    202     , fStringEndStream()
    203     , fContentAugmentStream(manager)
    204     , fDocumentContextStream()
    205     , fDocumentObjectStream()
    206 {
    207     fContentIdx = 0;
     187XMLParser::XMLParser(XMLReader & reader, XMLStringPool * uriPool, MemoryManager * manager)
     188: fContentIdx(0)
     189, fSymbolCount(0)
     190, fReferenceCount(0)
     191, fStringCount(0)
     192, fDocumentObjectCount(0)
     193, fScope(0)
     194, fErrorDepth(0)
     195, fMaxScope(0)
     196, fMaxAttributeCount(0)
     197, fGidStack()
     198, fElementIndex(-1)
     199, fElement()
     200, fChildren()
     201, fNoMore(true)
     202, fInMarkup(0)
     203, fHasIdentityConstraints(false)
     204, fElementCount(0)
     205, fCharacterSetAdapter(0)
     206, fEntityContentBuffer(0)
     207, fInElement(0)
     208, fContainsXsiTypeOrNil(0)
     209, fContentStream()
     210, fSymbolStream()
     211, fReferenceStream()
     212, fUriStream()
     213, fNamespaceContextStream()
     214, fStringEndStream()
     215, fContentAugmentStream(manager)
     216, fDocumentContextStream()
     217, fDocumentObjectStream()
     218, fLine(reader.fCurLine)
     219, fColumn(reader.fCurCol)
     220, fNamespaceResolver(uriPool, manager)
     221, fReader(reader)
     222#ifdef PAPI_EVENT_SET
     223, fPapiCounter(NEW_PAPI_COUNTER)
     224#endif
     225{
    208226    fStringEndPtr = &fStringEndStream[0];
    209227    fCursorEndPtr = &fContentStream[0];
     228
     229    START_PAPI_COUNTER(fPapiCounter, PAPI_MEASURE_TOTAL);
    210230}
    211231
     
    217237    delete fEntityContentBuffer;
    218238    fEntityContentBuffer = 0;
     239
     240    STOP_PAPI_COUNTER(fPapiCounter, PAPI_MEASURE_TOTAL);
     241    #ifdef PAPI_EVENT_SET
     242    XERCES_STD_QUALIFIER cout << "icXML," << XMLString::transcode(fReader.getSystemId()) << fPapiCounter << XERCES_STD_QUALIFIER endl;
     243    #endif
    219244}
    220245
    221246// -------------------------------------------------------------------------------------------
    222247
    223 IDISA_ALWAYS_INLINE
    224 void XMLParser::getCurrentLineCol
    225 (
    226     XMLFileLoc     & line
    227     , XMLFileLoc   & column
    228 ) const
    229 {
    230     line = 2;
    231     column = 1;
     248inline void XMLParser::getLocator(XMLFileLoc & line, XMLFileLoc & column) const
     249{
     250    line = fLine;
     251    column = fColumn;
     252}
     253
     254inline LineColumnPtrType XMLParser::calculateMarkupLocation(const LineColumnPtrType from, const LineColumnPtrType to, XMLFileLoc & line, XMLFileLoc & column)
     255{
     256    #ifndef LINE_COLUMN_TRACKER_USES_RAW_NUMBERS
     257    LineColumnPtrType ptr = from;
     258    while (ptr < to)
     259    {
     260        line += ptr[0];
     261        column += ptr[1];
     262        ptr += 2;
     263    }
     264    #else
     265    if (likely(from < to))
     266    {
     267        line = to[-2];
     268        column = to[-1];
     269    }
     270    else // TODO: pretty sure this else statement ought to be an error if it occurs but leaving it here to be safe. needs further evaluation.
     271    {
     272        line = from[0];
     273        column = from[1];
     274    }
     275    #endif
     276    return to;
    232277}
    233278
    234279XERCES_CPP_NAMESPACE_END
    235280
    236 #if !defined(XERCES_TMPLSINC)
    237 #include <icxmlc/XMLParserImpl.hpp>
    238 #endif
    239 
    240281#endif // XMLPARSER_H
  • icXML/icXML-devel/src/icxmlc/XMLParserDefs.hpp

    r3103 r3563  
    77/*
    88 * @author Nigel Medforth, nigelm -at- interational-characters.com
    9  * @version $Id: XMLParserDefs.hpp 295 2013-04-24 02:36:00Z nigelm $
     9 * @version $Id: XMLParserDefs.hpp 371 2013-09-05 21:51:18Z nigelm $
    1010 *
    1111 */
     
    1616#include <icxmlc/Array.hpp>
    1717#include <icxmlc/XMLConfig.hpp>
     18#include <icxercesc/validators/common/Grammar.hpp>
    1819
    1920XERCES_CPP_NAMESPACE_BEGIN
    2021
    21 #define INITIAL_LINE_COLUMN_SIZE ((INITIAL_CONTENT_BUFFER_SIZE / BLOCK_SIZE) + 2)
    22 #define INITIAL_STRING_LENGTH_SIZE (INITIAL_CONTENT_BUFFER_SIZE / 4)
    23 #define INITIAL_SYMBOL_SIZE (INITIAL_CONTENT_BUFFER_SIZE / 4)
    24 #define INITIAL_REFERENCE_SIZE (INITIAL_CONTENT_BUFFER_SIZE / 6)
    25 
    26 #if INITIAL_CONTENT_BUFFER_SIZE == 0
    27 #error "INITIAL_CONTENT_BUFFER_SIZE was not set or was set to 0!"
     22#define INITIAL_LINE_COLUMN_SIZE ((SEGMENT_SIZE / BLOCK_SIZE) + 2)
     23#define INITIAL_STRING_LENGTH_SIZE (SEGMENT_SIZE / 4)
     24#define INITIAL_SYMBOL_SIZE (SEGMENT_SIZE / 4)
     25#define INITIAL_REFERENCE_SIZE (SEGMENT_SIZE / 6)
     26
     27#if SEGMENT_SIZE == 0
     28#error "SEGMENT_SIZE was not set or was set to 0!"
    2829#endif
    2930
     
    4142    , Content =                         0
    4243    , IgnorableWhitespace =             8 | Content
    43     , EmptyTag =                        8 | StartTagWithoutAttributes
     44    , EmptyTag =                        8
    4445    , DefaultAttribute =                8 | Attribute
    45     , SchemaDefaultAttribute =          16 | DefaultAttribute
    46     , EmptyTagWithoutAttributes =       8 | StartTagWithoutAttributes
    47     , EmptyTagWithAttributes =          8 | StartTagWithAttributes
    48 
    49     , NamespaceAttribute =              0x80 | Attribute
    50     , Surpressed  =                     0x8000
     46    , SchemaDecl =                      16
     47    , SchemaDefaultAttribute =          SchemaDecl | Attribute
     48    , EmptyTagWithoutAttributes =       EmptyTag | StartTagWithoutAttributes
     49    , EmptyTagWithAttributes =          EmptyTag | StartTagWithAttributes
     50
     51    , AnyAttributeMask =                Attribute | DefaultAttribute | SchemaDefaultAttribute
    5152
    5253    , Entity =                          0xFFFE  // illegal in UTF-16
     
    6162    , HasCommentOrProcessingInstruction = 4
    6263};
     64
     65enum XMLDocumentObject
     66{
     67    AttributeObjectCount = 2
     68    , AttributePSVIObjectCount = 5
     69    , StartTagObjectCount = 2
     70    , EndTagObjectCount = 2
     71    , PartialElementPSVIObjectCount = 2
     72    , ElementPSVIObjectCount = 5
     73
     74    , ContentObjectCount = 1
     75
     76    , ProcessingInstructionObjectCount = 2
     77    , CommentObjectCount = 1
     78    , CDATAObjectCount = 1
     79};
     80
     81enum XMLDocumentContext
     82{
     83    HasPSVI = 0x20
     84};
     85
     86
    6387
    6488class XMLElementDecl;
     
    7195class XSElementDeclaration;
    7296class XSAttributeDeclaration;
     97
     98// NOTE: the DocumentObjectType is simply a more restrictive void* that allows casting without constantly
     99// using static_cast<...> for each of the supported types.
    73100
    74101union DocumentObjectType
     
    86113};
    87114
    88 #ifndef USE_HEAP_ALLOCATION_FOR_XML_PARSER
    89 typedef DynamicArray<XMLCh, INITIAL_CONTENT_BUFFER_SIZE * 2, sizeof(BytePack)> ContentStream;
     115typedef DynamicArray<XMLCh, SEGMENT_SIZE * 2, sizeof(BytePack)> ContentStream;
    90116typedef DynamicArray<BitBlock, INITIAL_LINE_COLUMN_SIZE> LineColStream;
    91117typedef DynamicArray<unsigned int, INITIAL_SYMBOL_SIZE> SymbolUriArray;
    92118typedef DynamicArray<gid_t, INITIAL_SYMBOL_SIZE> SymbolArray;
    93119typedef DynamicArray<gid_t, INITIAL_REFERENCE_SIZE> ReferenceArray;
    94 typedef DynamicArray<DocumentObjectType, INITIAL_CONTENT_BUFFER_SIZE / 2> DocumentObjectStream;
    95 typedef DynamicArray<unsigned int, INITIAL_CONTENT_BUFFER_SIZE / 2> DocumentContextStream;
    96 #else
    97 typedef DynamicArray<XMLCh, 0, sizeof(BytePack)> ContentStream;
    98 typedef DynamicArray<BitBlock, 0> LineColStream;
    99 typedef DynamicArray<unsigned int, 0> SymbolUriArray;
    100 typedef DynamicArray<gid_t, 0> SymbolArray;
    101 #endif
    102 
    103 class StringPtrArray : public
    104         #ifndef USE_HEAP_ALLOCATION_FOR_XML_PARSER
    105         DynamicArray<const XMLCh*, INITIAL_STRING_LENGTH_SIZE>
    106         #else
    107         DynamicArray<const XMLCh*, 0>
    108         #endif
     120typedef DynamicArray<DocumentObjectType, SEGMENT_SIZE / 2> DocumentObjectStream;
     121typedef DynamicArray<uint32_t, SEGMENT_SIZE / 2> DocumentContextStream;
     122typedef FixedArray<LineColumnDiffType, SEGMENT_SIZE * 2 / 2> LineColumnDiffStream;
     123
     124
     125union ContextHeaderType
     126{
     127    uint32_t value;
     128    uint8_t _8[sizeof(uint32_t) / sizeof(uint8_t)];
     129    uint16_t _16[sizeof(uint32_t) / sizeof(uint16_t)];
     130};
     131
     132class StringPtrArray : public DynamicArray<const XMLCh*, INITIAL_STRING_LENGTH_SIZE>
    109133{
    110134public:
    111         #ifndef USE_HEAP_ALLOCATION_FOR_XML_PARSER
    112135        StringPtrArray() : DynamicArray<const XMLCh*, INITIAL_STRING_LENGTH_SIZE>() { }
    113136        StringPtrArray(const size_t capacity) : DynamicArray<const XMLCh*, INITIAL_STRING_LENGTH_SIZE>(capacity) { }
    114         #else
    115         StringPtrArray() : DynamicArray<const XMLCh*, 0>(INITIAL_STRING_LENGTH_SIZE) { }
    116         StringPtrArray(const size_t capacity) : DynamicArray<const XMLCh*, 0>(capacity) { }
    117         #endif
    118137
    119138        IDISA_ALWAYS_INLINE
     
    321340typedef const StringPtrArray::Type * DelimiterPtrType;
    322341
     342typedef const LineColumnDiffStream::Type * LineColumnPtrType;
     343
    323344typedef typename ContentStreamA<0>::Type FakeContentStream;
    324345
     
    337358typedef typename DelimiterStreamA<1>::Type AugmentedDelimiterStream;
    338359
    339 
    340 
    341 typedef DocumentObjectStream::Type WriteableDocumentObjectType;
     360typedef const DocumentContextStream::Type DocumentContextType;
    342361typedef DocumentContextStream::Type WriteableDocumentContextType;
    343362
     363typedef const DocumentObjectType * DocumentObjectPtrType;
     364typedef const DocumentContextType * DocumentContextPtrType;
     365
     366typedef DocumentObjectType * WriteableDocumentObjectPtrType;
     367typedef WriteableDocumentContextType * WriteableDocumentContextPtrType;
     368
     369
    344370
    345371XERCES_CPP_NAMESPACE_END
  • icXML/icXML-devel/src/icxmlc/XMLParserImpl.c

    r3151 r3563  
    77/*
    88 * @author Nigel Medforth, nigelm -at- interational-characters.com
    9  * @version $Id: XMLParserImpl.c 313 2013-05-11 04:03:43Z nigelm $
     9 * @version $Id: XMLParserImpl.c 377 2013-09-23 23:13:04Z nigelm $
    1010 *
    1111 */
     
    1818#include <icxmlc/parsers/XMLWellFormednessParser.hpp>
    1919#include <icxmlc/parsers/XMLGrammarValidator.hpp>
     20#include <icxmlc/parsers/XMLIdentityConstraintValidator.hpp>
    2021
    2122XERCES_CPP_NAMESPACE_BEGIN
     
    6465
    6566    size_t bytesEaten;
    66     size_t symbolCount;
    67     size_t stringEndCount;
    68     size_t referenceCount;
    69 
    70         fCursorEndPtr =
    71                 fCharacterSetAdapter->parse
    72                 (
    73             input
    74             , avail
    75                         , noMore
    76             , const_cast<WritableContentPtrType>(&fContentStream[fContentIdx])
    77             , &fSymbolStream[fSymbolCount]
    78             , symbolCount
    79             , &fReferenceStream[fReferenceCount]
    80             , referenceCount
    81             , &fStringEndStream[fStringCount]
    82             , stringEndCount
    83             , fMarkupCount
    84                         , bytesEaten
    85                 );
     67
     68    fCursorEndPtr = &fContentStream[fContentIdx];
     69
     70    fCharacterSetAdapter->parse
     71    (
     72        input
     73        , avail
     74        , noMore
     75        , *this
     76        , bytesEaten
     77    );
    8678
    8779        fSymbolIdx = 0;
    88     fSymbolCount += symbolCount;
    8980    fReferenceIdx = 0;
    90     fReferenceCount += referenceCount;
    91     fStringCount += stringEndCount;
    92     fUriIdx = 0;
    9381    fStringEndPtr = &fStringEndStream[0];
    94     fDocumentContextIdx = 0;
    95     fDocumentObjectIdx = 0;
    96     fContextIdx = 0;
    9782    fContentIdx = 0;
    9883
    99     if (unlikely(referenceCount > 0 && !fEntityContentBuffer))
     84    if (unlikely(fReferenceCount > 0 && !fEntityContentBuffer))
    10085    {
    10186        fEntityContentBuffer = new (fScanner.getMemoryManager()) XMLBuffer(1023, fScanner.getMemoryManager());
     
    128113)
    129114{
    130     const size_t SEGMENT_SIZE = (BUFFER_BLOCKS * BLOCK_SIZE) / sizeof(XMLCh);
    131 
    132     fCursorEndPtr = &fContentStream[0];
     115    enum { UTF16_SEGMENT_SIZE = ((SEGMENT_SIZE) / sizeof(XMLCh)) };
     116
    133117    size_t offset = 0;
    134118
     
    137121    fStringCount = 0;
    138122    fMarkupCount = 0;
     123    fCursorEndPtr = &fContentStream[0];
    139124
    140125    XMLUTF16CharacterSetAdapter * adapter =
    141126        reinterpret_cast<XMLUTF16CharacterSetAdapter*>(fCharacterSetAdapter);
    142127
     128
     129    // TODO: potential line column tracking issue: will this handle extremely long sequences of replacement text?
     130
    143131    for (;;)
    144132    {
    145133        size_t avail = length - offset;
    146134        fNoMore = 1;
    147         if (unlikely(avail > SEGMENT_SIZE))
    148         {
    149             avail = SEGMENT_SIZE;
     135        if (unlikely(avail > UTF16_SEGMENT_SIZE))
     136        {
     137            avail = UTF16_SEGMENT_SIZE;
    150138            fNoMore = 0;
    151139        }
    152140
     141        DEBUG_MESSAGE(" **** SCAN INTERNAL PAGE @ " << offset << " -> avail=" << avail << " noMore=" << fNoMore)
     142
    153143        size_t bytesEaten = 0;
    154         size_t symbolCount = 0;
    155         size_t stringEndCount = 0;
    156         size_t referenceCount = 0;
    157         size_t markupCount = 0;
    158 
    159         fCursorEndPtr =
    160             adapter->parseInternal
    161             (
    162                 &input[offset]
    163                 , avail
    164                 , fNoMore
    165                 , const_cast<WritableContentPtrType>(fCursorEndPtr)
    166                 , &fSymbolStream[fSymbolCount]
    167                 , symbolCount
    168                 , &fReferenceStream[fReferenceCount]
    169                 , referenceCount
    170                 , &fStringEndStream[fStringCount]
    171                 , stringEndCount
    172                 , markupCount
    173                 , bytesEaten
    174             );
    175 
    176         DEBUG_MESSAGE("bytesEaten=" << bytesEaten);
    177 
    178         fSymbolCount += symbolCount;
    179         fReferenceCount += referenceCount;
    180         fStringCount += stringEndCount;
    181         fMarkupCount += markupCount;
     144
     145        adapter->parseInternal
     146        (
     147            &input[offset]
     148            , avail
     149            , fNoMore
     150            , *this
     151            , bytesEaten
     152        );
    182153
    183154        if (fNoMore) break;
     
    185156        offset += bytesEaten;
    186157
    187         DEBUG_REFERENCE_MESSAGE(" **** NEXT INTERNAL PAGE @ " << offset << "! ****")
    188 
    189         enum { INPUT_SIZE = (BUFFER_BLOCKS * BLOCK_SIZE) / sizeof(XMLCh) };
     158        DEBUG_MESSAGE(" **** NEXT INTERNAL PAGE @ " << offset << "! ****")
    190159
    191160        /** ----------------------- BUFFER CONTENT STREAM --------------------------- **/
     
    194163        ptrdiff_t cursorOffset = (fCursorEndPtr - &fContentStream[0]);
    195164
    196         if (fContentStream.capacity() < (cursorOffset + INPUT_SIZE))
     165        if (fContentStream.capacity() < (cursorOffset + UTF16_SEGMENT_SIZE))
    197166        {
    198167            const XMLCh * const contentBuf0 = &fContentStream[0];
     
    208177        /** -------------------- MOVE STRING END POINTERS BACK ------------------------ **/
    209178
    210         if (fStringEndStream.capacity() < (fStringCount + (INPUT_SIZE / 4)))
     179        if (fStringEndStream.capacity() < (fStringCount + (UTF16_SEGMENT_SIZE / 4)))
    211180        {
    212181            fStringEndStream.resizeToFit(fStringCount, fStringEndStream.capacity() * 2);
     
    215184        /** ------------------------ BUFFER SYMBOL STREAM ------------------------------ **/
    216185
    217         if (fSymbolStream.capacity() < (fSymbolCount + (INPUT_SIZE / 2)))
     186        if (fSymbolStream.capacity() < (fSymbolCount + (UTF16_SEGMENT_SIZE / 2)))
    218187        {
    219188            fSymbolStream.resizeToFit(fSymbolCount, fSymbolStream.capacity() * 2);
     
    222191        /** ----------------------- BUFFER REFERENCE STREAM ---------------------------- **/
    223192
    224         if (fReferenceStream.capacity() < (fReferenceCount + (INPUT_SIZE / 3 + 1)))
     193        if (fReferenceStream.capacity() < (fReferenceCount + (UTF16_SEGMENT_SIZE / 3 + 1)))
    225194        {
    226195            fReferenceStream.resizeToFit(fReferenceCount, fReferenceStream.capacity() * 2);
     
    232201    fContentIdx = 0;
    233202    fStringEndPtr = &fStringEndStream[0];   
     203
     204
     205
    234206
    235207    XMLWellFormednessParser<XMLScannerType> wfScanner(*this, adapter->getSymbolTable(), adapter->getReferenceTable(), fScanner);
     
    242214    toFill.fCDATACount = wfScanner.fCDATACount;
    243215    toFill.fSymbolCount = wfScanner.fSymbolCount;
    244     toFill.fReferenceCount = wfScanner.fReferenceCount;
     216    toFill.fReferenceCount = fReferenceCount;
    245217    toFill.fStringEndCount = wfScanner.fStringCount;
    246218}
     
    268240
    269241template<class XMLScannerType>
    270 void
     242bool
    271243XMLParserImpl<XMLScannerType>::
    272244buildElementPage()
     
    278250    validateGrammar();   
    279251
    280     if (unlikely(fScanner.getDocHandler() == 0))
    281     {
    282         fDocumentObjectCount = 0;
     252    if (fDocumentDesseminator)
     253    {
     254        fDocumentDesseminator->reset(this, fScanner.getPSVIModel(), fScanner.getRootElemName());
     255        return true;
    283256    }
    284257    else
    285258    {
    286         fDocumentDesseminator.resizeAttributeArray(fMaxAttributeCount, fScanner.getMemoryManager());
     259        return false;
    287260    }
    288261}
     
    294267XMLParserImpl<XMLScannerType>::
    295268scanElementPage()
    296 {
    297     while (scanNext());
     269{     
     270    START_PAPI_COUNTER(fPapiCounter, PAPI_MEASURE_DD);
     271
     272    DEBUG_MESSAGE("######################################################################");
     273    DEBUG_MESSAGE("PRINT ELEMENT PAGE:");
     274    DEBUG_MESSAGE("######################################################################");
     275    if (fDocumentDesseminator)
     276    {
     277        fDocumentDesseminator->scanPage();
     278    }
     279
     280    STOP_PAPI_COUNTER(fPapiCounter, PAPI_MEASURE_DD);
    298281
    299282    return inElement();
     
    310293bool XMLParserImpl<XMLScannerType>::scanNext()
    311294{
    312     return fDocumentDesseminator.next();
     295    return (fDocumentDesseminator) ? fDocumentDesseminator->scanNext() : false;
    313296}
    314297
     
    325308{
    326309    checkWellformedness<XMLParser::Miscellaneous>();
    327 
    328     while (scanNext());
    329 
     310    if (unlikely(fDocumentObjectCount && fDocumentDesseminator))
     311    {
     312        fDocumentDesseminator->reset(this, 0, 0);
     313        fDocumentDesseminator->scanPage();
     314    }
    330315    return !fNoMore;
    331316}
     
    342327        contentPtr = *fStringEndPtr++ + 1;
    343328        fContentIdx++;
     329        fMarkupCount--;
    344330        fInMarkup = true;
    345331    }
     
    372358template<XMLParser::DocumentStateType DocStateType>
    373359void XMLParserImpl<XMLScannerType>::checkWellformedness()
    374 {
     360
     361    START_PAPI_COUNTER(fPapiCounter, PAPI_MEASURE_WF);
     362
    375363    if (DocStateType == XMLParser::Element)
    376364    {
     
    388376            wfScanner.fElementCount
    389377            , wfScanner.fAttributeCount
    390             , wfScanner.fReferenceCount
     378            , fReferenceCount
    391379            , wfScanner.fCommentCount
    392380            , wfScanner.fProcessingInstructionCount
    393381            , wfScanner.fCDATACount
    394             , false
    395             , false
     382            , (fScanner.getPSVIHandler() != NULL)
    396383        );
    397384
    398385        // based on the WF check, also pre-expand any streams as needed.
    399         const size_t elementCount = (fElementIndex + wfScanner.fElementCount);
     386        const size_t elementCount = (fElementIndex + wfScanner.fElementCount + 1);
    400387        if (unlikely(fElement.capacity() <= elementCount))
    401388        {
    402             fElement.resizeToFit(fElementIndex + 1, elementCount);
    403             DEBUG_MESSAGE(" -- resizing fElement to fit " << elementCount << " -> " << fElement.capacity())
     389            fElement.resizeToFit(fElementIndex + 1, max(elementCount, fElement.capacity() * 2));
     390            DEBUG_MESSAGE(" -- resizing fElement to fit " << fElement.capacity())
    404391        }
    405392
     
    408395            fNamespaceResolver.setMaxScope(fMaxScope);
    409396            fChildren.resizeToFit(fScope, fNamespaceResolver.getMaxScope());
    410             fGidStack.resizeToFit(fScope, fNamespaceResolver.getMaxScope());
    411397            fContentFlag.resizeToFit(fScope, fMaxScope);
    412398            DEBUG_MESSAGE(" -- resizing scopes to fit " << fMaxScope << " -> " << fNamespaceResolver.getMaxScope() << ',' << fChildren.capacity() << ',' << fGidStack.capacity() << ',' << fContentFlag.capacity())
     
    415401        if (unlikely(fUriStream.capacity() <= fUriCount))
    416402        {
    417             fUriStream.resizeToFit(fUriIdx, fUriCount);
     403            fUriStream.resizeToFit(0, fUriCount);
    418404            DEBUG_MESSAGE(" -- resizing fUriStream to fit " << fUriCount << " -> " << fUriStream.capacity())
    419405        }
    420406
    421407        const size_t contextCount = (wfScanner.fElementCount * 2);
    422         if (unlikely(fContextStream.capacity() <= contextCount))
    423         {
    424             fContextStream.resizeToFit(fContextIdx, contextCount);
    425             DEBUG_MESSAGE(" -- resizing fContextStream to fit " << contextCount << " -> " << fContextStream.capacity())
     408        if (unlikely(fNamespaceContextStream.capacity() <= contextCount))
     409        {
     410            fNamespaceContextStream.resizeToFit(0, contextCount);
     411            DEBUG_MESSAGE(" -- resizing fNamespaceContextStream to fit " << contextCount << " -> " << fNamespaceContextStream.capacity())
    426412        }
    427413    }
    428414    else
    429415    {
     416        fDocumentAccumulator.reset();
     417
    430418        XMLWellFormednessParser<XMLScannerType> wfScanner(*this, fSymbolTable, fReferenceTable, fScanner);
    431419
    432420        wfScanner.checkWellformedness<DocStateType>(&fDocumentAccumulator);
    433 
    434         if (unlikely(fScanner.getDocHandler() == 0))
    435         {
    436             fDocumentObjectCount = 0;
    437         }
    438     }
     421    }
     422
     423    STOP_PAPI_COUNTER(fPapiCounter, PAPI_MEASURE_WF);
    439424}
    440425
     
    444429void XMLParserImpl<XMLScannerType>::resolveDocumentPageNamespaces()
    445430{
    446     if (!fScanner.getDoNamespaces() || fMarkupCount == 0)
    447     {
    448         return;
    449     }
     431    START_PAPI_COUNTER(fPapiCounter, PAPI_MEASURE_NR);
    450432
    451433    XMLSchemaLoader<XMLScannerType> schemaLoader(NULL); // fMemoryManager
     
    467449        }
    468450    }
     451
     452    STOP_PAPI_COUNTER(fPapiCounter, PAPI_MEASURE_NR);
    469453}
    470454
     
    474458void XMLParserImpl<XMLScannerType>::validateGrammar()
    475459{
     460    START_PAPI_COUNTER(fPapiCounter, PAPI_MEASURE_GV);
     461
    476462    XMLGrammarValidator<XMLScannerType> gv(*this, fNamespaceResolver, fSymbolTable, fReferenceTable, fScanner, fDocumentAccumulator);
    477463    fInElement = gv.validateGrammar();
     
    485471    fStringEndPtr = gv.fStringEndPtr;
    486472    fMarkupCount = gv.fMarkupCount;
     473    //fLine = gv.fLine;
     474    //fColumn = gv.fColumn;
     475
     476    if (gv.fHasIdentityConstraints)
     477    {
     478        DEBUG_MESSAGE("######################################################################");
     479        DEBUG_MESSAGE("IDENTITY CONSTRAINT VALIDATION:");
     480        DEBUG_MESSAGE("######################################################################");
     481
     482        XMLIdentityConstraintValidator icValidator
     483        (
     484            fDocumentContextStream
     485            , fDocumentObjectStream
     486            , fNamespaceContextStream
     487            , fNamespaceResolver
     488            , fDocumentObjectCount
     489            , fScanner.getIdentityConstraintHandler()
     490            , fScanner.fValidationContext
     491            , fScanner.getMemoryManager()
     492        );
     493
     494        fHasIdentityConstraints = (icValidator.validateIdentityConstraints(gv.fMaxAttributeCount) > 0);
     495    }
     496
     497    STOP_PAPI_COUNTER(fPapiCounter, PAPI_MEASURE_GV);
    487498}
    488499
     
    493504{
    494505    const XMLCh * cursorPtr = &fContentStream[fContentIdx];
    495     const size_t symbolIdx = fSymbolIdx;
    496     const ptrdiff_t stringIndex = (fStringEndPtr - &fStringEndStream[0]);
    497 
    498     DEBUG_MESSAGE("stringIndex=" << stringIndex << " of " << fStringCount);
    499 
    500     DEBUG_MESSAGE("fSymbolIdx=" << fSymbolIdx << " of " << fSymbolCount);
    501 
    502         /** ------------------- BUFFER LINE/COL TRACKING STREAM --------------------- **/
    503 
    504 
     506    const ptrdiff_t stringIndex = (fStringEndPtr - fStringEndStream.first());
     507
     508    DEBUG_MESSAGE(" -- contentIdx=" << fContentIdx << " of " << (fCursorEndPtr - fContentStream.first()))
     509    DEBUG_MESSAGE(" -- stringIndex=" << stringIndex << " of " << fStringCount)
     510    DEBUG_MESSAGE(" -- fSymbolIdx=" << fSymbolIdx << " of " << fSymbolCount)
     511    DEBUG_MESSAGE(" -- fReferenceIdx=" << fReferenceIdx << " of " << fReferenceCount)
    505512
    506513        /** ----------------------- BUFFER CONTENT STREAM --------------------------- **/
     
    538545        /** ------------------------ BUFFER SYMBOL STREAM ------------------------------ **/
    539546
    540     fUriStream.copyToFront(symbolIdx, fSymbolCount);
    541     fContextStream.copyToFront(symbolIdx, fSymbolCount);
    542     fSymbolCount = fSymbolStream.copyToFront(symbolIdx, fSymbolCount);
     547    fSymbolCount = fSymbolStream.copyToFront(fSymbolIdx, fSymbolCount);
    543548
    544549    /** ----------------------- BUFFER REFERENCE STREAM ----------------------------- **/
  • icXML/icXML-devel/src/icxmlc/XMLParserImpl.hpp

    r3151 r3563  
    77/*
    88 * @author Nigel Medforth, nigelm -at- interational-characters.com
    9  * @version $Id: XMLParserImpl.hpp 307 2013-05-08 23:02:44Z nigelm $
     9 * @version $Id: XMLParserImpl.hpp 375 2013-09-22 22:19:15Z nigelm $
    1010 *
    1111 */
     
    3636        template<typename ScannerType> friend class XMLGrammarValidator;
    3737        friend class XMLDocumentDisseminator;
     38        friend class XMLIdentityConstraintValidator;
    3839
    3940        public:
     
    4748                XMLParserImpl
    4849                (
    49             XMLScannerType *const               scanner
    50             , MemoryManager *const              manager
     50            XMLReader &                         reader
     51            , XMLScannerType &                  scanner
     52            , MemoryManager * const             manager
    5153                );
    5254
     
    99101                void prepareForNextDocumentPage();
    100102
    101         void buildElementPage();
     103        bool buildElementPage();
    102104
    103105        bool scanMiscellaneousPage();
     
    105107        void verifyProlog();
    106108
     109        virtual XMLScanner & getScanner() const;
     110
    107111    private:
    108112
    109113        template <XMLParser::DocumentStateType DocStateType>
    110         IDISA_ALWAYS_INLINE
     114        //IDISA_ALWAYS_INLINE
    111115        void checkWellformedness();
    112116
    113         IDISA_ALWAYS_INLINE
     117        //IDISA_ALWAYS_INLINE
    114118        void resolveDocumentPageNamespaces();
    115119
    116         IDISA_ALWAYS_INLINE
     120        //IDISA_ALWAYS_INLINE
    117121        void validateGrammar();
    118122
    119123        private:
    120124
    121         XMLNamespaceResolver                            fNamespaceResolver;
    122125        XMLSymbolTable                                          fSymbolTable;
    123126        XMLReferenceTable                   fReferenceTable;
    124127        XMLScannerType &                    fScanner;
    125128        XMLDocumentAccumulator              fDocumentAccumulator;               
    126         XMLDocumentDisseminator             fDocumentDesseminator;
     129        XMLDocumentDisseminator * const     fDocumentDesseminator;
    127130};
    128131
     
    130133XMLParserImpl<XMLScannerType>::XMLParserImpl
    131134(
    132     XMLScannerType * const              scanner
     135    XMLReader &                         reader
     136    , XMLScannerType &                  scanner
    133137        , MemoryManager * const                         manager   
    134138)
    135 : XMLParser(manager)
    136 , fNamespaceResolver(scanner->getUriResolver(), manager)
    137 , fSymbolTable(scanner, fNamespaceResolver, fReferenceTable, manager)
    138 , fReferenceTable(scanner, fSymbolTable, manager)
    139 , fScanner(*scanner)
     139: XMLParser(reader, scanner.fGrammarResolver->getURIStringPool(), manager)
     140, fSymbolTable(&scanner, this->fNamespaceResolver, fReferenceTable, scanner.fGrammarResolver->getStringPool(), manager)
     141, fReferenceTable(&scanner, fSymbolTable, manager)
     142, fScanner(scanner)
    140143, fDocumentAccumulator(*this)
    141 , fDocumentDesseminator(*this, scanner->getDocHandler(), manager)
     144, fDocumentDesseminator(scanner.getDocHandler() ? scanner.getDocHandler()->createDocumentDisseminator() : NULL)
    142145{
    143     fScanner.setUriResolver(&fNamespaceResolver);
     146    fScanner.initNamespaceContext(&this->fNamespaceResolver, 0);
    144147}
    145148
     
    147150XMLParserImpl<XMLScannerType>::~XMLParserImpl()
    148151{
    149     fScanner.setUriResolver(0);
     152    fScanner.initNamespaceContext(0, 0);
     153    delete fDocumentDesseminator;
     154    fScanner.setLocator(&fScanner.fReaderMgr);
     155}
     156
     157
     158template<class XMLScannerType>
     159XMLScanner & XMLParserImpl<XMLScannerType>::getScanner() const
     160{
     161    return fScanner;
    150162}
    151163
  • icXML/icXML-devel/src/icxmlc/XMLReferenceTable.cpp

    r3151 r3563  
    2525)
    2626{
     27    DEBUG_REFERENCE_MESSAGE("XMLReferenceTable::expandReference(...," << length << ',' << inAttVal << ')')
     28
    2729    // add the ref to the appropriate table
    2830    XMLReference reference;
    2931    reference.fLength = length;
    3032    reference.fKey = fEntityPool.insert(entityName, length);
    31     reference.fId = fReferenceTable.count();
    32 
    33     fReferenceTable.add(reference);
     33    reference.fId = fReferenceTable.add(reference);
    3434
    3535    if (unlikely(reference.fId == fReplacementTextList.capacity()))
     
    5252    XMLCh * referenceName = janReferenceName.get();
    5353    referenceName[transcodedLength] = 0;
     54
    5455    #ifdef PRINT_DEBUG_MESSAGE
    5556    replacementText.fRefNameString = XMLString::transcode(referenceName, fMemoryManager);
     
    5859
    5960    bool expanded = 0;
    60     bool isExternal = 0;
    61     // need to set these to what the CSA says they are.
    62     XMLFileLoc line = 0;
    63     XMLFileLoc column = 0;
    6461
    6562    //  If the next char is a pound, then its a character reference...
     
    6865//      3.3.3 Attribute-Value Normalization
    6966//      For [each] character reference, append the referenced character to the normalized value.
    70 
    71         expanded = expandCharacterReference(referenceName + 1, transcodedLength - 1, entity, replacementText.fType);
     67        expanded = expandCharacterReference(referenceName + 1, transcodedLength - 1, entity, replacementText);
    7268    }
    7369    else // it must be a predefined or general entity
    7470    {
    75         const ReplacementType replacementTextType[2] =
    76         {
    77             XMLReplacementText::GeneralEntity
    78             , XMLReplacementText::PredefinedEntity
    79         };
    80 
    8171        if (likely(XMLNameChar::test(referenceName, transcodedLength)))
    8272        {
    83             bool isPredefined = 0;
    84             expanded = fScanner.expandEntityReference(referenceName, length, inAttVal, entity, isPredefined, isExternal, line, column);
    85             replacementText.fType = replacementTextType[isPredefined];
     73            expanded = fScanner.expandEntityReference(referenceName, length, inAttVal, entity, replacementText);
    8674        }
    8775        else
     
    9886    }   
    9987
     88    // * IF we encounter an error, we fake leaving it unexpanded by reinserting the 'unmodified' entity name into
     89    // the ';' slot in the content stream.
    10090    if (unlikely(!expanded))
    101     {
    102         // if we encounter an error, construct the full ref name...
     91    {       
    10392        entity.reset();
    10493        entity.append(chAmpersand);
     
    113102
    114103    fReplacementTextList[reference.fId] = replacementText;
    115 
    116     if (unlikely(isExternal))
    117     {
    118         // if we were dealing with an external entity, pop the reader that was parsing it
    119         fScanner.popReader();
    120     }
    121104
    122105    return reference.fId;
     
    147130    {
    148131        const bool hasOpenAngleBracket = XMLStringU::indexOf<chOpenAngle>(replacementText, length) != -1;
    149 
    150         DEBUG_REFERENCE_MESSAGE(" -- hasOpenAngleBracket=" << hasOpenAngleBracket)
    151132
    152133        if (inAttVal | !hasOpenAngleBracket)
     
    381362    , size_t                        length
    382363    , XMLBuffer &                   entity
    383     , ReplacementType &             type
     364    , XMLReplacementText &          replacementText
    384365)
    385366{
     
    399380
    400381    const uint8_t CONVERSION_TABLE[112] =
    401         { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
    402         , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
    403         , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
    404         ,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1
    405         , -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1
    406         , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
    407         , -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1
     382        { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
     383        , 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
     384        , 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
     385        ,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
     386        , 0xFF, 10, 11, 12, 13, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
     387        , 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
     388        , 0xFF, 10, 11, 12, 13, 14, 15, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
    408389        };
    409390
     
    462443        XMLCh character = XMLCh(characterValue);
    463444        entity.set(&character, 1);
    464         type = XMLReplacementText::CharacterReference;
     445        replacementText.fType = XMLReplacementText::CharacterReference;
    465446    }
    466447    else if (characterValue >= 0x10000 && characterValue <= 0x10FFFF)
     
    471452        character[1] = XMLCh((characterValue & 0x3FF) | static_cast<XMLUInt64>(0xDC00));
    472453        entity.set(character, 2);
    473         type = XMLReplacementText::SurrogateCharacterReference;
     454        replacementText.fType = XMLReplacementText::SurrogateCharacterReference;
    474455        fHasSurrogateCharacterReferences = true;
    475456    }
     
    493474)
    494475{
    495     // should the entire replacementText be transcoded into the input character set? could simplify some code but could
    496     // reduce expansion performance. Are there any character sets when converted to UTF16 and back to the input character
     476    // should the entire replacementText be transcoded into the input character set? could simplify some code but would
     477    // require that the XMLDefaultCharacterSetAdapter is capable of processing both the input and UTF16 data and relating
     478    // the positions correctly. Are there any character sets when converted to UTF16 and back to the input character
    497479    // set result in invalid characters?
    498     XMLNamespaceResolver * const resolver = fScanner.getUriResolver();
     480    const XMLNamespaceResolver * const namespaceResolver = fScanner.getNamespaceResolver();
     481    unsigned int * namespaceContextId = fScanner.getNamespaceContextId();
    499482
    500483    {
     
    515498        // note: the refAdapter uses the original scanner to resolve any entities, not the empty scanner
    516499        // used for the parsing work. That only exists to properly template the scanner.
    517         XMLParserImpl<XMLScanner> refParser(&fScanner, fMemoryManager);
     500        XMLParserImpl<XMLScanner> refParser(*fScanner.getCurrentReader(), fScanner, fMemoryManager);
    518501        refParser.init(&refAdapter, transcoder, 0, 0, fScanner.getXMLVersion());
    519502        refAdapter.init(&fScanner, fSymbolTable, *this, 0, 0);
     
    521504        refParser.scanInternalDocumentPage(replacementText, length, toFill);
    522505
    523         DEBUG_MESSAGE(" *** scanned internal document page")
    524 
    525506        // restore the reference and symbol table's original parameters
    526507        fSymbolTable.fResumeSymbol = resumeSymbol;
     
    540521        {
    541522            const size_t dist = refParser.fStringEndStream[i] - contentStream;
     523            assert (dist <= toFill.fContentLength);
    542524            delimiterStream[i] = &toFill.fContentStream[dist];
    543525        }
     
    559541        }
    560542
    561         DEBUG_MESSAGE(" *** parsed reference with markup 1")
    562     }
    563 
    564     // note: the XMLParser automatically sets the UriResolver in the scanner to 0 upon deletion; this restores it.
    565     fScanner.setUriResolver(resolver);
    566 
    567     DEBUG_MESSAGE(" *** parsed reference with markup 2")
     543        size_t markupDelimiterCount = refParser.fMarkupCount + refParser.fReferenceCount;
     544        if (markupDelimiterCount)
     545        {
     546            toFill.fLineColumnStream = fLineColumnPool.insert(refParser.fLineColumnStream.first(), markupDelimiterCount);
     547        }
     548    }
     549
     550    // note: the XMLParser automatically sets the UriResolver of the XMLScanner to 0 when it goes out of scope; this restores it.
     551    fScanner.initNamespaceContext(namespaceResolver, namespaceContextId);
    568552
    569553    return 1;
  • icXML/icXML-devel/src/icxmlc/XMLReferenceTable.hpp

    r3151 r3563  
    77/*
    88 * @author Nigel Medforth, nigelm -at- interational-characters.com
    9  * @version $Id: XMLReferenceTable.hpp 304 2013-05-06 22:38:14Z nigelm $
     9 * @version $Id: XMLReferenceTable.hpp 387 2013-10-28 23:33:23Z nigelm $
    1010 *
    1111 */
     
    2323#include <icxercesc/util/TransService.hpp>
    2424#include <icxmlc/XMLReplacementText.hpp>
     25#include <icxmlc/bit_vector_t.hpp>
    2526#include <icxmlc/XMLConfig.hpp>
    2627
     
    113114        , fGidPool(manager)
    114115                , fStringEndPool(manager)
     116        , fLineColumnPool(manager)
    115117                , fResumeRef(0)
    116118        , fSomeGeneralEntityContainsReferences(0)
     
    131133        const XMLReplacementText & operator[](const gid_t gid) const
    132134                {
    133             assert (gid < count());
    134135            return fReplacementTextList[gid];
    135136                }
     
    137138        XMLReplacementText & operator[](const gid_t gid)
    138139        {
    139             assert (gid < count());
    140140            return fReplacementTextList[gid];
    141141        }
     
    228228            , size_t                        length
    229229            , XMLBuffer &                   character
    230             , ReplacementType &             type
     230            , XMLReplacementText &          replacementText
    231231        );
    232232
     
    237237
    238238        IDISA_ALWAYS_INLINE
    239         static bool invert(BitBlock * stream, const ssize_t pos);
     239        static void invert(BitBlock * stream, const ssize_t pos);
    240240
    241241        void reportEntity(const gid_t entityId, const XMLErrs::Codes errorCode) const;
     
    243243        void reportUnterminatedEntity(const XMLCh * reference, XMLBuffer & toFill) const;
    244244
    245         private:
     245    private:
    246246
    247247        HashTable<XMLReference, XMLByte, 32>                        fReferenceTable;
     
    253253                StringPool<XMLByte, 128, 1>                                                                     fEntityPool;
    254254        StringPool<XMLCh, 1024, 1>                                                                      fContentPool;
    255         StringPool<gid_t, 16, 0>                                                                        fGidPool;
    256         StringPool<ContentPtrType, 16, 0>                                                       fStringEndPool;
     255        StringPool<gid_t, 128, 0>                                                                       fGidPool;
     256        StringPool<ContentPtrType, 128, 0>                                                      fStringEndPool;
     257        StringPool<LineColumnDiffType, 128, 0>                      fLineColumnPool;
    257258
    258259        XMLScanner &                                                fScanner;
     
    266267        MemoryManager * const                                                                           fMemoryManager;
    267268};
    268 
    269 #define DEBUG_REFERENCE_MESSAGE(x) DEBUG_SYMBOL_MESSAGE(x)
    270269
    271270/// ----------------------------------------------------------------------------------------------------
     
    315314                    startPosition = entityItr.pos() + CodeUnitSize;
    316315
    317         case 1:     if (unlikely(!entityItr.next()))
     316        default:    if (unlikely(!entityItr.next()))
    318317                    {
    319318                        bytesEaten = offset + startPosition >> Internal;
     
    395394
    396395                }
     396                break;
    397397    }
    398398
     
    425425    #endif
    426426
    427     DEBUG_REFERENCE_MESSAGE("XMLReferenceTable::fResumeRef=" << fResumeRef << ", bytesEaten=" << bytesEaten)
     427    DEBUG_REFERENCE_MESSAGE("XMLReferenceTable::fResumeRef=" << fResumeRef << ", bytesEaten=" << bytesEaten);
    428428
    429429    return entityPtr - entityStream;
     
    439439)
    440440{
     441    DEBUG_REFERENCE_MESSAGE("XMLReferenceTable::addOrFind(...)");
    441442    // in order to distinguish between an entity ref inside an attribute value and one in content, we include the closing ';'
    442443    // with any attribute value in the symbol gid.
    443444    gid_t refId = fReferenceTable.find(entityName, length);
     445
     446    DEBUG_REFERENCE_MESSAGE("refId=" << refId);
     447
    444448    if (unlikely(refId == -1))
    445449    {
     
    458462)
    459463{
     464    DEBUG_REFERENCE_MESSAGE("XMLReferenceTable::addOrFindInternal(...)");
    460465    DynamicArray<XMLByte, 128, sizeof(BytePack)> entityKey(length * 4 + 3);
    461 
    462466    XMLSize_t charsEaten = 0;
    463467    size_t transcodedLength = fTranscoder->transcodeTo(entityName, length, &entityKey[0], entityKey.capacity(), charsEaten, XMLTranscoder::UnRep_Throw);
     
    466470}
    467471
    468 #ifdef __ARCH_64
    469472bool XMLReferenceTable::extract(const BitBlock * stream, const size_t pos)
    470473{
    471     // abstract this function to a static bit test?
    472     ubitblock block;
    473     block._128 = bitblock::load_aligned(stream + (pos >> LOG_2_BLOCK_SIZE));
    474     const uint64_t temp = block._64[(pos & (BLOCK_SIZE - 1)) >> CONST_LOG_2(64)];
    475     return static_cast<bool>((temp >> (pos & 63)) & 1);
    476 }
    477 
    478 bool XMLReferenceTable::invert(BitBlock * stream, const ssize_t pos)
    479 {
    480     const uint64_t ONE = 1;
    481     const ssize_t index = pos / BLOCK_SIZE;
    482     ubitblock block;
    483     block._128 = bitblock::load_aligned(stream + index);
    484     const uint64_t offset = (pos >> CONST_LOG_2(64)) & ((BLOCK_SIZE / 64) - ONE);
    485     const uint64_t inversion = (ONE << (pos & 63));
    486     block._64[offset] ^= inversion;
    487     bitblock::store_aligned(block._128, stream + index);
    488 }
    489 #else
    490 bool XMLReferenceTable::extract(const BitBlock * stream, const size_t pos)
    491 {
    492     // abstract this function to a static bit test?
    493     ubitblock block;
    494     block._128 = bitblock::load_aligned(stream + (pos >> LOG_2_BLOCK_SIZE));
    495     const uint32_t temp = block._32[(pos & (BLOCK_SIZE - 1)) >> CONST_LOG_2(32)];
    496     return static_cast<bool>((temp >> (pos & 31)) & 1);
    497 }
    498 
    499 bool XMLReferenceTable::invert(BitBlock * stream, const ssize_t pos)
    500 {
    501     const uint32_t ONE = 1;
    502     const ssize_t index = pos / BLOCK_SIZE;
    503     ubitblock block;
    504     block._128 = bitblock::load_aligned(stream + index);
    505     const uint32_t offset = (pos >> CONST_LOG_2(32)) & ((BLOCK_SIZE / 32) - ONE);
    506     const uint32_t inversion = (ONE << (pos & 31));
    507     block._32[offset] ^= inversion;
    508     bitblock::store_aligned(block._128, stream + index);
    509 }
    510 #endif
    511 
     474    const IntAlignedBitVector vec(bitblock::load_aligned(stream + (pos >> LOG_2_BLOCK_SIZE)));
     475    return vec.extract(pos & (BLOCK_SIZE - 1));
     476}
     477
     478void XMLReferenceTable::invert(BitBlock * stream, const ssize_t pos)
     479{
     480    const size_t index = (pos >> LOG_2_BLOCK_SIZE);
     481    IntAlignedBitVector vec(bitblock::load_aligned(stream + index));
     482    vec.invert(pos & (BLOCK_SIZE - 1));
     483    bitblock::store_aligned(vec._b, stream + index);
     484}
    512485
    513486/// ----------------------------------------------------------------------------------------------------
  • icXML/icXML-devel/src/icxmlc/XMLReplacementText.hpp

    r3103 r3563  
    44#include <icxmlc/XMLParserDefs.hpp>
    55#include <icxmlc/XMLConfig.hpp>
     6#include <icxercesc/framework/XMLEntityDecl.hpp>
    67
    78XERCES_CPP_NAMESPACE_BEGIN
     9
     10// TODO: there should be distinct general entity and non-general entity replacement texts to reduce the storage space.
    811
    912class XMLReferenceTable;
     
    4548    , fMaxScope(0)
    4649    , fMaxAttributeCount(0)
     50    , fSystemId(0)
     51    , fPublicId(0)
     52    , fLine(0)
     53    , fColumn(0)
     54    , fLineColumnStream(0)
    4755    #ifdef PRINT_DEBUG_MESSAGE
    4856    , fRefNameString(0)
     
    7987        fStringEndStream = ref.fStringEndStream;
    8088        fMaxScope = ref.fMaxScope;
    81         fMaxAttributeCount = ref.fMaxAttributeCount;
     89        fMaxAttributeCount = ref.fMaxAttributeCount;       
     90        fSystemId = ref.fSystemId;
     91        fPublicId = ref.fPublicId;
     92        fLine = ref.fLine;
     93        fColumn = ref.fColumn;
     94        fLineColumnStream = ref.fLineColumnStream;
    8295        #ifdef PRINT_DEBUG_MESSAGE
    8396        fRefNameString = XMLString::replicate(ref.fRefNameString);
     
    144157    DelimiterPtrType                fStringEndStream;
    145158
     159    const XMLCh *                   fSystemId;
     160    const XMLCh *                   fPublicId;
     161    XMLFileLoc                      fLine;
     162    XMLFileLoc                      fColumn;
     163    LineColumnPtrType               fLineColumnStream;
     164
    146165    uint32_t                        fMaxScope;
    147166    uint32_t                        fMaxAttributeCount;
  • icXML/icXML-devel/src/icxmlc/XMLScanIterator.hpp

    r3103 r3563  
    77/*
    88 * @author Nigel Medforth, nigelm -at- interational-characters.com
    9  * @version $Id: XMLScanIterator.hpp 294 2013-04-17 02:02:39Z nigelm $
     9 * @version $Id: XMLScanIterator.hpp 384 2013-10-21 22:28:13Z nigelm $
    1010 *
    1111 */
     
    103103                BytePack t1 = simd<16>::eq(b1, mask1);
    104104
    105         const iterator_t value = hsimd<8>::signmask(hsimd128<16>::packss(t1, t0));
     105        const iterator_t value = hsimd<8>::signmask(hsimd<16>::packss(t1, t0));
    106106
    107107        return value;
     
    279279                t1 = simd_or(t1, simd<16>::eq(b1, mask2));
    280280
    281                 return hsimd<8>::signmask(hsimd128<16>::packss(t1, t0));
     281        return hsimd<8>::signmask(hsimd<16>::packss(t1, t0));
    282282        }
    283283
     
    447447                t1 = simd_or(t1, simd<16>::eq(b1, mask3));
    448448
    449                 return hsimd<8>::signmask(hsimd128<16>::packss(t1, t0));
     449        return hsimd<8>::signmask(hsimd<16>::packss(t1, t0));
    450450        }
    451451
     
    624624        t1 = simd_or(t1, simd<16>::eq(b1, mask4));
    625625
    626         return hsimd<8>::signmask(hsimd128<16>::packss(t1, t0));
     626        return hsimd<8>::signmask(hsimd<16>::packss(t1, t0));
    627627    }
    628628
     
    819819        t1 = simd_or(t1, within<CharLo2, CharHi2>(b1));
    820820
    821         return hsimd<8>::signmask(hsimd128<16>::packss(t1, t0));
     821        return hsimd<8>::signmask(hsimd<16>::packss(t1, t0));
    822822    }
    823823
     
    10171017        t1 = simd_or(t1, within<CharLo4, CharHi4>(b1));
    10181018
    1019         return hsimd<8>::signmask(hsimd128<16>::packss(t1, t0));
     1019        return hsimd<8>::signmask(hsimd<16>::packss(t1, t0));
    10201020    }
    10211021
  • icXML/icXML-devel/src/icxmlc/XMLStreamIterator.hpp

    r3103 r3563  
    77/*
    88 * @author Nigel Medforth, nigelm -at- interational-characters.com
    9  * @version $Id: XMLStreamIterator.hpp 247 2013-01-26 02:01:29Z nigelm $
     9 * @version $Id: XMLStreamIterator.hpp 391 2013-11-12 22:25:47Z nigelm $
    1010 *
    1111 */
     
    1414#define XMLSTREAMITERATOR_HPP
    1515
     16#include <icxmlc/bit_vector_t.hpp>
    1617#include <icxmlc/XMLConfig.hpp>
    1718
  • icXML/icXML-devel/src/icxmlc/XMLStringU.hpp

    r3103 r3563  
    77/*
    88 * @author Nigel Medforth, nigelm -at- interational-characters.com
    9  * @version $Id: XMLStringU.hpp 293 2013-04-16 02:16:44Z nigelm $
     9 * @version $Id: XMLStringU.hpp 385 2013-10-22 21:21:29Z nigelm $
    1010 *
    1111 */
     
    2424XERCES_CPP_NAMESPACE_BEGIN
    2525
    26 #if BLOCK_SIZE != 128
    27 #pragma error "XMLStringU::match8 only supports BLOCK_SIZE 128!"
    28 #endif
    29 
    3026#ifdef __GNUC__
    3127#define PURE __attribute__((pure))
     
    141137    union PackedWord
    142138        {
    143                 XMLCh __string[8];
    144                 BytePack value;
     139        XMLCh __string[sizeof(bitblock128_t) / sizeof(XMLCh)];
     140        bitblock128_t value;
    145141        } STRING = {{ c0, c1, c2, c3, c4, c5, c6, c7 }};
    146142
    147         const BytePack fixedVal = bitblock::load_aligned(&STRING.value);
    148         const BytePack inputVal = bitblock::load_unaligned((const BytePack*)string);
    149     const unsigned int matchingChars = hsimd<8>::signmask(simd<16>::eq(inputVal, fixedVal));
    150         const unsigned int one = 1;
    151         const unsigned int matchMask = ((one << (length * sizeof(XMLCh))) - one);
    152 
    153         return (matchingChars & matchMask) == matchMask;
    154 }
     143    const bitblock128_t fixedVal = bitblock128::load_aligned(&STRING.value);
     144    const bitblock128_t inputVal = bitblock128::load_unaligned((const bitblock128_t*)string);
     145    const unsigned int matchingChars = hsimd128<8>::signmask(simd128<16>::eq(inputVal, fixedVal));
     146
     147    enum { MATCH_MASK = ((1 << (length * sizeof(XMLCh))) - 1) };
     148
     149    return (matchingChars & MATCH_MASK) == MATCH_MASK;
     150}
     151
     152#if BLOCK_SIZE == 128
    155153
    156154template < XMLSize_t length
     
    162160                           match8<length - 8, c8, c9, c10, c11, c12, c13, c14, c15>(string + 8);
    163161}
     162
     163#else
     164
     165template < XMLSize_t length
     166         , XMLCh c0, XMLCh c1, XMLCh c2, XMLCh c3, XMLCh c4, XMLCh c5, XMLCh c6, XMLCh c7
     167         , XMLCh c8, XMLCh c9, XMLCh c10, XMLCh c11, XMLCh c12, XMLCh c13, XMLCh c14, XMLCh c15>
     168bool XMLStringU::match16(const XMLCh * string)
     169{
     170    union PackedWord
     171    {
     172        XMLCh __string[sizeof(bitblock256_t) / sizeof(XMLCh)];
     173        bitblock256_t value;
     174    } STRING = {{ c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15 }};
     175
     176    const bitblock256_t fixedVal = bitblock256::load_aligned(&STRING.value);
     177    const bitblock256_t inputVal = bitblock256::load_unaligned((const bitblock256_t*)string);
     178    const unsigned int matchingChars = hsimd256<8>::signmask(simd256<16>::eq(inputVal, fixedVal));
     179
     180    enum { MATCH_MASK = ((static_cast<uint64_t>(1) << static_cast<uint64_t>(length * sizeof(XMLCh))) - 1) };
     181
     182    return (matchingChars & MATCH_MASK) == MATCH_MASK;
     183}
     184
     185#endif
    164186
    165187template < XMLSize_t length
     
    182204    union PackedWord
    183205    {
    184         XMLCh __string[8];
    185         BytePack value;
     206        XMLCh __string[sizeof(bitblock128_t) / sizeof(XMLCh)];
     207        bitblock128_t value;
    186208    } XML = {{ chLatin_x, chLatin_m, chLatin_l, chNull, chLatin_X, chLatin_M, chLatin_L, chColon }};
    187209
    188     BytePack input = bitblock::load_unaligned((const BytePack*)string);
     210    bitblock128_t input = bitblock128::load_unaligned((const bitblock128_t*)string);
    189211    // shift the first 4 characters to the end of the register so that we can test and see whether
    190212    // it matches (x|X)(m|M)(l|L)(<null>|:) in parallel
    191     input = mvmd<sizeof(XMLCh) * 8>::slli<4>(input);
    192     input = simd_or(input, mvmd<sizeof(XMLCh) * 8>::srli<4>(input));
     213    input = mvmd128<sizeof(XMLCh) * 8>::slli<4>(input);
     214    input = simd_or(input, mvmd128<sizeof(XMLCh) * 8>::srli<4>(input));
    193215    // test the string and ...
    194     input = simd<sizeof(XMLCh) * 8>::eq(input, bitblock::load_aligned(&XML.value));
    195     size_t match = hsimd<8>::signmask(input);
     216    input = simd128<sizeof(XMLCh) * 8>::eq(input, bitblock128::load_aligned(&XML.value));
     217    size_t match = hsimd128<8>::signmask(input);
    196218    // OR any potential "XML" matches with the potential "xml" matches.
    197219    match |= (match >> (4 * sizeof(XMLCh)));
     
    273295                index += 2;
    274296
    275                 const unsigned int mask = hsimd<8>::signmask(hsimd128<8>::packss(b1, b0));
     297        const unsigned int mask = hsimd<8>::signmask(hsimd<8>::packss(b1, b0));
    276298
    277299                if (unlikely(mask != 0xFFFF))
     
    329351        enum
    330352        {
    331                 XMLCHS_PER_BYTEPACK = (sizeof(BytePack) / sizeof(XMLCh))
    332                 , LOG_2_XMLCHS_PER_BYTEPACK = CONST_LOG_2(XMLCHS_PER_BYTEPACK)
     353                XMLCHS_PER_BYTEPACK = (sizeof(BytePack) / sizeof(XMLCh))               
    333354        };
     355
     356    enum
     357    {
     358        LOG_2_XMLCHS_PER_BYTEPACK = CONST_LOG_2(XMLCHS_PER_BYTEPACK)
     359    };
    334360
    335361        const BytePack mask = simd<16>::constant<character>();
     
    348374                BytePack b1 = simd<16>::eq(s1, mask);
    349375
    350         pos = hsimd<8>::signmask(hsimd128<8>::packss(b1, b0));
     376        pos = hsimd<8>::signmask(hsimd<8>::packss(b1, b0));
    351377
    352378        if (pos)
     
    368394        BytePack b1 = simd<16>::eq(s1, mask);
    369395
    370         pos = hsimd<8>::signmask(hsimd128<8>::packss(b1, b0));
     396        pos = hsimd<8>::signmask(hsimd<8>::packss(b1, b0));
    371397    }
    372398    else if (remainingLength > 0)
     
    480506        const BytePack * src = reinterpret_cast<const BytePack*>(string);
    481507
    482         enum
    483         {
    484                 XMLCHS_PER_BYTEPACK = (sizeof(BytePack) / sizeof(XMLCh))
    485                 , LOG_2_SIZE_OF_XMLCH = CONST_LOG_2(sizeof(XMLCh))
    486                 , LOG_2_XMLCHS_PER_BYTEPACK = CONST_LOG_2(XMLCHS_PER_BYTEPACK)
    487         };
     508    enum { XMLCHS_PER_BYTEPACK = (sizeof(BytePack) / sizeof(XMLCh)) };
     509    enum { LOG_2_SIZE_OF_XMLCH = CONST_LOG_2(sizeof(XMLCh)) };
     510    enum { LOG_2_XMLCHS_PER_BYTEPACK = CONST_LOG_2(XMLCHS_PER_BYTEPACK) };
    488511
    489512        XMLSize_t index = 0;
  • icXML/icXML-devel/src/icxmlc/XMLSymbol.c

    r3151 r3563  
    77/*
    88 * @author Nigel Medforth, nigelm -at- interational-characters.com
    9  * @version $Id: XMLSymbol.c 312 2013-05-10 20:53:22Z nigelm $
     9 * @version $Id: XMLSymbol.c 357 2013-06-23 02:15:10Z nigelm $
    1010 *
    1111 */
     
    5959XMLElementDecl * XMLSymbol::getElemDecl(unsigned int uriId, unsigned int scope, size_t & index) const
    6060{
    61     DEBUG_MESSAGE(*this << ".getElemDecl(" << uriId << ',' << scope << ')')
    62 
    6361    index = 0;
    6462    for (;;)
     
    8583void XMLSymbol::setElemDecl(unsigned int uriId, unsigned int scope, XMLElementDecl * elemDecl)
    8684{
    87     DEBUG_MESSAGE(*this << ".setElemDecl(" << uriId << ',' << scope << ',' << elemDecl << ')')
    88 
    8985    size_t index = 0;
    9086    for (;;)
     
    112108void XMLSymbol::setElemDecl(const size_t index, unsigned int uriId, unsigned int scope, XMLElementDecl * elemDecl)
    113109{
    114     DEBUG_MESSAGE(*this << ".setElemDecl(" << index << ',' << uriId << ',' << scope << ',' << elemDecl << ')')
    115 
    116110    if (unlikely(index == fElemDeclList.capacity()))
    117111    {
     
    136130
    137131
    138 XMLSymbol::XMLSymbol(MemoryManager* const manager)
     132XMLSymbol::XMLSymbol(XMLStringPool * const qNameManager)
    139133: fRawLength(0)
    140134, fRawSymbol(0)
    141135, fPrefixId(XMLNamespaceResolver::fUnknownUriId)
    142136, fLocalPartId(XMLNamespaceResolver::fUnknownUriId)
    143 , fQName(manager)
     137, fQName(qNameManager)
    144138, fAttr(NULL)
    145139, fDefaultAttributeList(0)
  • icXML/icXML-devel/src/icxmlc/XMLSymbol.hpp

    r3151 r3563  
    77/*
    88 * @author Nigel Medforth, nigelm -at- interational-characters.com
    9  * @version $Id: XMLSymbol.hpp 316 2013-05-13 20:03:50Z nigelm $
     9 * @version $Id: XMLSymbol.hpp 339 2013-06-10 23:40:24Z nigelm $
    1010 *
    1111 */
     
    3333class XMLReferenceTable;
    3434class Grammar;
     35class XMLStringPool;
    3536
    3637struct ElementDeclRef
     
    127128    typedef DynamicArray<ElementDeclRef, 1> ElementDeclList;
    128129
    129     inline XMLSymbol(MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager);
     130    inline XMLSymbol(XMLStringPool * const qNameManager = 0);
    130131
    131132        inline ~XMLSymbol();
     
    133134        XMLSymbol & operator=(const XMLSymbol & symbol)
    134135        {
    135         DEBUG_MESSAGE("XMLSymbol=(symbol)")
    136136                fRawLength = symbol.fRawLength;
    137137                fRawSymbol = symbol.fRawSymbol;
     
    156156        IDISA_ALWAYS_INLINE
    157157    const XMLCh * const getName() const { return fQName.getRawName(); }
    158 
    159         IDISA_ALWAYS_INLINE
    160     const XMLSize_t getNameLength() const { return fQName.getRawLength(); }
    161158
    162159        IDISA_ALWAYS_INLINE
  • icXML/icXML-devel/src/icxmlc/XMLSymbolTable.cpp

    r3151 r3563  
    77/*
    88 * @author Nigel Medforth, nigelm -at- interational-characters.com
    9  * @version $Id: XMLSymbolTable.cpp 316 2013-05-13 20:03:50Z nigelm $
     9 * @version $Id: XMLSymbolTable.cpp 359 2013-06-23 23:41:45Z nigelm $
    1010 *
    1111 */
     
    1717#include <icxercesc/internal/XMLScanner.hpp>
    1818#include <icxercesc/framework/XMLBuffer.hpp>
     19#include <xercesc/util/StringPool.hpp>
    1920#include <icxercesc/validators/schema/SchemaSymbols.hpp>
    2021#include <icxercesc/validators/common/Grammar.hpp>
     
    3031)
    3132{
    32     XMLSymbol entry(fMemoryManager);
     33    XMLSymbol entry(fNCNameManager);
    3334    entry.fRawLength = length;
    3435    entry.fRawSymbol = fSymbolPool.insert(key, length);
     
    3738    fTranscoder->transcodeFrom(key, length, symbol);
    3839    const XMLSize_t symbolLength = symbol.getLen();
    39     Janitor<XMLCh> janSymbolName(XMLString::replicate(symbol.getRawBuffer(), symbolLength, fMemoryManager));
    40     XMLCh * symbolName = janSymbolName.get();
     40    XMLCh * symbolName = symbol.getRawBuffer();
    4141
    4242    /// VERIFY THAT THE CHARACTERS IN THE SYMBOL ARE LEGAL ACCORDING TO XML SPECIFICATIONS
     
    5252    doNamespaceResolution(symbolName, symbolLength, colon, entry);
    5353
    54     initQName(symbolName, length, colon, entry, entry.fQName);
     54    initQName(symbolName, length, colon, entry);
    5555
    5656    checkForDefaultAttributes(entry);
    57 
    58     janSymbolName.release();
    5957
    6058    return fSymbolTable.add(entry);
     
    7068)
    7169{
    72     XMLSymbol entry(fMemoryManager);
    73     entry.fRawLength = unencodedLength;
    74     entry.fRawSymbol = fSymbolPool.insert(unencodedKey, unencodedLength);
    75 
    76     Janitor<XMLCh> janSymbolName(XMLString::replicate(key, length, fMemoryManager));
    77     XMLCh * symbolName = janSymbolName.get();
    78     symbolName[length] = 0;
    79 
    80 
    8170    /// VERIFY THAT THE CHARACTERS IN THE SYMBOL ARE LEGAL ACCORDING TO XML SPECIFICATIONS
    8271    if (unlikely(!XMLNameChar::test(key, length)))
    8372    {
    84         DEBUG_SYMBOL_MESSAGE("ERROR! failed XMLNameChar validation! " << symbolName)
     73        DEBUG_SYMBOL_MESSAGE("ERROR! failed XMLNameChar validation! " << key)
    8574        fScanner.emitError(XMLErrs::ExpectedElementName);
    8675        return -1;
    8776    }
    8877
     78
     79    XMLSymbol entry(fNCNameManager);
     80    entry.fRawLength = unencodedLength;
     81    entry.fRawSymbol = fSymbolPool.insert(unencodedKey, unencodedLength);
     82
     83    Janitor<XMLCh> janSymbolName(XMLString::replicate(key, length, fMemoryManager));
     84    XMLCh * symbolName = janSymbolName.get();
     85    symbolName[length] = chNull;
     86
    8987    int colon = -1;
    9088
    9189    doNamespaceResolution(symbolName, length, colon, entry);
    9290
    93     initQName(symbolName, length, colon, entry, entry.fQName);
     91    initQName(symbolName, length, colon, entry);
    9492
    9593    checkForDefaultAttributes(entry);
    9694
    97     janSymbolName.release();
    98 
    9995    return fSymbolTable.add(entry);
    10096}
    10197
    102 void XMLSymbolTable::initQName(XMLCh * name, const XMLSize_t length, const int colon, const XMLSymbol & entry, QName & qName) const
    103 {
    104     qName.fURIId = XMLNamespaceResolver::fEmptyUriId;
    105     if (likely(colon != -1))
    106     {
    107         qName.fPrefix = const_cast<XMLCh*>(fNamespaceResolver.getPrefixForId(entry.fPrefixId));
    108         qName.fPrefixLen = colon - 1;
    109         qName.fLocalPart = const_cast<XMLCh*>(fNCNameTable[entry.fLocalPartId]);
    110         qName.fLocalPartLen = length - colon;
    111     }
    112     else
    113     {
    114         qName.fPrefix = const_cast<XMLCh*>(XMLUni::fgEmptyString);
    115         qName.fPrefixLen = 0;
    116         qName.fLocalPart = name;
    117         qName.fLocalPartLen = length;
    118     }
    119     qName.fRawName = name;
    120     qName.fNameBuf = name;
     98void XMLSymbolTable::initQName(XMLCh * name, const XMLSize_t length, const int colon, XMLSymbol & entry) const
     99{
     100    QName temp(name, colon, XMLNamespaceResolver::fEmptyUriId, fNCNameManager);
     101    entry.fQName.setValues(temp);
    121102}
    122103
     
    167148        }
    168149
    169         entry.fLocalPartId = fNCNameTable.addOrFind(&name[colon + 1], length - colon - 1);
     150        entry.fLocalPartId = fNCNameManager->addOrFind(&name[colon + 1]); // , length - colon - 1
    170151    }
    171152}
  • icXML/icXML-devel/src/icxmlc/XMLSymbolTable.hpp

    r3157 r3563  
    77/*
    88 * @author Nigel Medforth, nigelm -at- interational-characters.com
    9  * @version $Id: XMLSymbolTable.hpp 318 2013-05-16 02:45:25Z nigelm $
     9 * @version $Id: XMLSymbolTable.hpp 387 2013-10-28 23:33:23Z nigelm $
    1010 *
    1111 */
     
    3636class XMLUTF8CharacterSetAdapter;
    3737class XMLUTF16CharacterSetAdapter;
     38class XMLStringPool;
    3839
    3940/* -------------------------------------------------------------------------------------------- */
     
    6465        , XMLNamespaceResolver &        namespaceResolver
    6566        , XMLReferenceTable &           referenceTable
     67        , XMLStringPool * const         ncNameManager
    6668        , MemoryManager * const         manager
    6769        )
    6870        : fSymbolTable()
    6971        , fSymbolPool(manager)
    70     , fNCNameTable(manager)
    7172    , fNamespaceResolver(namespaceResolver)
    7273    , fReferenceTable(referenceTable)
     
    7677    , fDefaultAttributePool(manager)
    7778    , fHasDefaultAttributes(0)
     79    , fNCNameManager(ncNameManager)
    7880        , fMemoryManager(manager)
    7981        {
    80         fNCNameTable.add(Type, SchemaSymbols::fgXSI_TYPE, 4);
    81         fNCNameTable.add(Nil, SchemaSymbols::fgATT_NILL, 3);
    82         fNCNameTable.add(SchemaLocation, SchemaSymbols::fgXSI_SCHEMALOCATION, 14);
    83         fNCNameTable.add(NoNamespaceSchemaLocation, SchemaSymbols::fgXSI_NONAMESPACESCHEMALOCATION, 25);
     82        DEBUG_SYMBOL_MESSAGE("XMLSymbolTable::XMLSymbolTable(" << scanner << ',' << &namespaceResolver << ',' << &referenceTable << ',' << ncNameManager << ',' << manager << ')')
    8483        }
    8584
     
    104103    const XMLCh * getNCName(const gid_t id) const
    105104    {
    106         return fNCNameTable[id];
     105        return fNCNameManager->getValueForId(id);
    107106    }
    108107
     
    185184
    186185    IDISA_ALWAYS_INLINE
    187     void initQName(XMLCh * name, const XMLSize_t length, const int colon, const XMLSymbol & entry, QName & qName) const;
     186    void initQName(XMLCh * name, const XMLSize_t length, const int colon, XMLSymbol & entry) const;
    188187
    189188private:
     
    191190    HashTable<XMLSymbol, XMLByte, INITIAL_SYMBOL_TABLE_CAPACITY>                fSymbolTable;
    192191    StringPool<XMLByte, INITIAL_SYMBOL_TABLE_STRING_POOL_SIZE>                  fSymbolPool;
    193 
    194     XMLStringHash<XMLStringPoolEntry, INITIAL_SYMBOL_TABLE_STRING_POOL_SIZE>    fNCNameTable;
    195192
    196193    XMLNamespaceResolver &                                                      fNamespaceResolver;
     
    202199    bool                                                                        fResumeSymbol;
    203200
     201
    204202    StringPool<XMLElementDefaultAttribute, 16>                                  fDefaultAttributePool;
    205203    bool                                                                        fHasDefaultAttributes;
    206204
    207 
     205    XMLStringPool * const                                                       fNCNameManager;
    208206    MemoryManager *     const                                                       fMemoryManager;
    209207};
     
    249247                    startPosition = symbolItr.pos();
    250248
    251         case 1:     if (unlikely(!symbolItr.next()))
     249        default:    if (unlikely(!symbolItr.next()))
    252250                    {
    253251                        bytesEaten = offset + startPosition >> Internal;
  • icXML/icXML-devel/src/icxmlc/XMLUTF16CharacterSetAdapter.cpp

    r3151 r3563  
    77/*
    88 * @author Nigel Medforth, nigelm -at- interational-characters.com
    9  * @version $Id: XMLUTF16CharacterSetAdapter.cpp 315 2013-05-12 22:34:37Z nigelm $
     9 * @version $Id: XMLUTF16CharacterSetAdapter.cpp 391 2013-11-12 22:25:47Z nigelm $
    1010 *
    1111 */
     
    3131#include <simd-lib/bitblock_iterator.hpp>
    3232
     33#include <icxmlc/bitstream_iterator.hpp>
     34#include <icxmlc/simd_deletion.hpp>
     35
    3336#include <icxmlc/XMLMultiliteral.h>
    3437#include <icxmlc/PopCounter.hpp>
     
    3841#include <icxmlc/XMLLineColTracker.hpp>
    3942#include <icxmlc/XMLReferenceTable.hpp>
    40 #include <icxmlc/XMLParserDefs.hpp>
     43#include <icxmlc/XMLParser.hpp>
    4144#include <icxmlc/XMLConfig.hpp>
    4245
     
    4851// --------------------------------------------------------------------------------------
    4952
    50 #define do_right8_shifts(vec, rshift1, rshift2, rshift4) \
    51 do { \
    52         BitBlock s2; \
    53     vec = simd<8>::sub(vec, simd<16>::srli<1>(simd_and(rshift1, vec))); \
    54         s2 = simd_and(rshift2, vec);\
    55         vec = simd_or(simd<16>::srli<2>(s2), simd_xor(vec, s2));\
    56         s2 = simd_and(rshift4, vec);\
    57         vec = simd_or(simd<16>::srli<4>(s2), simd_xor(vec, s2));\
    58 } while(0)
    59 
    60 #define del_info_8(delmask, rshift1, rshift2, rshift4) \
    61 do { \
    62         BitBlock del8_trans2; \
    63         BitBlock del8_trans4; \
    64         BitBlock shift_bits; \
    65         rshift1 = simd_xor(simd<8>::slli<1>(delmask), simd<8>::slli<2>(delmask)); \
    66         rshift1 = simd_xor(rshift1, simd<8>::slli<2>(rshift1)); \
    67         rshift1 = simd_xor(rshift1, simd<8>::slli<4>(rshift1)); \
    68         /* Transition to even delcount: odd delcount to left, this one deleted. */ \
    69         del8_trans2 = simd_and(rshift1, delmask); \
    70         /* Odd number of transition positions to left. */ \
    71         rshift2 = simd_xor(simd<8>::slli<1>(del8_trans2), simd<8>::slli<2>(del8_trans2)); \
    72         rshift2 = simd_xor(rshift2, simd<8>::slli<2>(rshift2)); \
    73         rshift2 = simd_xor(rshift2, simd<8>::slli<4>(rshift2)); \
    74         /* Transition positions: odd |del2count| to left, this one a transition to even. */ \
    75         del8_trans4 = simd_and(rshift2, del8_trans2); \
    76         rshift4 = simd_xor(simd<8>::slli<1>(del8_trans4), simd<8>::slli<2>(del8_trans4)); \
    77         rshift4 = simd_xor(rshift4, simd<8>::slli<2>(rshift4)); \
    78         rshift4 = simd_xor(rshift4, simd<8>::slli<4>(rshift4)); \
    79         /* Only move bits that are not deleted. */ \
    80         rshift1 = simd_andc(rshift1, delmask); \
    81         rshift2 = simd_andc(rshift2, delmask); \
    82         rshift4 = simd_andc(rshift4, delmask); \
    83         /* Update |del8_rshift2| to apply after |del8_rshift1|. */ \
    84         rshift2 = simd<8>::sub(rshift2, simd<16>::srli<1>(simd_and(rshift1, rshift2))); \
    85         /* Update |del8_rshift4| to apply after |del8_rshift2| and |del8_rshift1|. */ \
    86         rshift4 = simd<8>::sub(rshift4, simd<16>::srli<1>(simd_and(rshift1, rshift4))); \
    87         shift_bits = simd_and(rshift2, rshift4); \
    88         rshift4 = simd_or(simd<16>::srli<2>(shift_bits), simd_xor(rshift4, shift_bits)); \
    89 } while(0)
    90 
    9153IDISA_ALWAYS_INLINE
    92 static BitBlock del_count(BitBlock delmask)
     54void XMLUTF16CharacterSetAdapter::writeContentInputStream(const U16lo & u16lo, const U16hi & u16hi,const Callouts & callouts, ContentInputStream & cis) const
    9355{
    94     return simd<8>::sub(simd<8>::constant<8>(), simd<8>::popcount(delmask));
     56    // would there be any advantage to using store functions that do not pollute the cache? i.e., using _mm_stream_si128 or _mm256_stream_si256?
     57    bitblock::store_aligned(u16lo.bit_0, &cis.lo[0]);
     58    bitblock::store_aligned(u16lo.bit_1, &cis.lo[1]);
     59    bitblock::store_aligned(u16lo.bit_2, &cis.lo[2]);
     60    bitblock::store_aligned(u16lo.bit_3, &cis.lo[3]);
     61    bitblock::store_aligned(u16lo.bit_4, &cis.lo[4]);
     62    bitblock::store_aligned(u16lo.bit_5, &cis.lo[5]);
     63    bitblock::store_aligned(u16lo.bit_6, &cis.lo[6]);
     64    bitblock::store_aligned(u16lo.bit_7, &cis.lo[7]);
     65    bitblock::store_aligned(u16hi.bit_0, &cis.hi[0]);
     66    bitblock::store_aligned(u16hi.bit_1, &cis.hi[1]);
     67    bitblock::store_aligned(u16hi.bit_2, &cis.hi[2]);
     68    bitblock::store_aligned(u16hi.bit_3, &cis.hi[3]);
     69    bitblock::store_aligned(u16hi.bit_4, &cis.hi[4]);
     70    bitblock::store_aligned(u16hi.bit_5, &cis.hi[5]);
     71    bitblock::store_aligned(u16hi.bit_6, &cis.hi[6]);
     72    bitblock::store_aligned(u16hi.bit_7, &cis.hi[7]);
     73    // write the delimiters out for the CSG
     74    bitblock::store_aligned(callouts.StringEnds, &cis.delimiters);
     75    bitblock::store_aligned(callouts.Ref_closer, &cis.references);
    9576}
    9677
    97 XMLCh * XMLUTF16CharacterSetAdapter::generateContentStream
     78
     79void XMLUTF16CharacterSetAdapter::generateContentStream
    9880(
    9981    const ContentInputStream *      contentInputStream
    10082    , const BitBlock *              deletionMaskStream
    10183    , size_t                        count
    102     , XMLCh *                       contentStream   
    103     , const XMLCh     **                        stringEndStream
    104     , gid_t     *                   referenceStream
    105     ,           size_t &                stringEndCount
    106     ,           size_t &                referenceCount
    107 )
     84    , XMLParser &                   parser
     85) const
    10886{
    109     gid_t * referencePtr = referenceStream;
    110     gid_t * generalEntityReferencePtr = referenceStream;
    111     const XMLCh ** stringEndPtr = stringEndStream;
    112 
    113     if (unlikely(!bitblock::all(*deletionMaskStream)))
    114     {
    115         // const size_t leadingNullChars = BLOCK_SIZE - bitblock::popcount(bitblock::load_aligned(deletionMaskStream));
     87    gid_t * referencePtr = &(parser.fReferenceStream[parser.fReferenceCount]);
     88    gid_t * generalEntityReferencePtr = referencePtr;
     89    const XMLCh ** stringEndPtr = &(parser.fStringEndStream[parser.fStringCount]);
     90    XMLCh * contentStream = const_cast<WritableContentPtrType>(parser.fCursorEndPtr);
     91
     92    if (unlikely(bitblock::any(*deletionMaskStream)))
     93    {
    11694        contentStream++;
    11795    }
     
    125103        /* --------------------------------------------------------------------- */
    126104
    127         const BitBlock delmask = bitblock::load_aligned(++deletionMaskStream);
    128         BitBlock shift1, shift2, shift4;
    129         del_info_8(delmask, shift1, shift2, shift4);
    130         ubitblock del;
    131         del._128 = del_count(delmask);
     105        const BitBlock delmask = bitblock::load_aligned(deletionMaskStream + index + 1);
     106
     107        DefaultParallelDeletion deletionAlgorithm(delmask);
     108        DefaultStreamCompressor streamCompressor(delmask);
    132109
    133110        BitBlock L[8];
    134111        BitBlock H[8];
    135112
    136         L[0] = bitblock::load_aligned(&cs.lo[0]);
    137         L[1] = bitblock::load_aligned(&cs.lo[1]);
    138         L[2] = bitblock::load_aligned(&cs.lo[2]);
    139         L[3] = bitblock::load_aligned(&cs.lo[3]);
    140         L[4] = bitblock::load_aligned(&cs.lo[4]);
    141         L[5] = bitblock::load_aligned(&cs.lo[5]);
    142         L[6] = bitblock::load_aligned(&cs.lo[6]);
    143         L[7] = bitblock::load_aligned(&cs.lo[7]);
    144 
    145         do_right8_shifts(L[0], shift1, shift2, shift4);
    146         do_right8_shifts(L[1], shift1, shift2, shift4);
    147         do_right8_shifts(L[2], shift1, shift2, shift4);
    148         do_right8_shifts(L[3], shift1, shift2, shift4);
    149         do_right8_shifts(L[4], shift1, shift2, shift4);
    150         do_right8_shifts(L[5], shift1, shift2, shift4);
    151         do_right8_shifts(L[6], shift1, shift2, shift4);
    152         do_right8_shifts(L[7], shift1, shift2, shift4);
    153 
    154         H[0] = bitblock::load_aligned(&cs.hi[0]);
    155         H[1] = bitblock::load_aligned(&cs.hi[1]);
    156         H[2] = bitblock::load_aligned(&cs.hi[2]);
    157         H[3] = bitblock::load_aligned(&cs.hi[3]);
    158         H[4] = bitblock::load_aligned(&cs.hi[4]);
    159         H[5] = bitblock::load_aligned(&cs.hi[5]);
    160         H[6] = bitblock::load_aligned(&cs.hi[6]);
    161         H[7] = bitblock::load_aligned(&cs.hi[7]);
    162 
    163         do_right8_shifts(H[0], shift1, shift2, shift4);
    164         do_right8_shifts(H[1], shift1, shift2, shift4);
    165         do_right8_shifts(H[2], shift1, shift2, shift4);
    166         do_right8_shifts(H[3], shift1, shift2, shift4);
    167         do_right8_shifts(H[4], shift1, shift2, shift4);
    168         do_right8_shifts(H[5], shift1, shift2, shift4);
    169         do_right8_shifts(H[6], shift1, shift2, shift4);
    170         do_right8_shifts(H[7], shift1, shift2, shift4);
     113        L[0] = deletionAlgorithm.apply(bitblock::load_aligned(&cs.lo[0]));
     114        L[1] = deletionAlgorithm.apply(bitblock::load_aligned(&cs.lo[1]));
     115        L[2] = deletionAlgorithm.apply(bitblock::load_aligned(&cs.lo[2]));
     116        L[3] = deletionAlgorithm.apply(bitblock::load_aligned(&cs.lo[3]));
     117        L[4] = deletionAlgorithm.apply(bitblock::load_aligned(&cs.lo[4]));
     118        L[5] = deletionAlgorithm.apply(bitblock::load_aligned(&cs.lo[5]));
     119        L[6] = deletionAlgorithm.apply(bitblock::load_aligned(&cs.lo[6]));
     120        L[7] = deletionAlgorithm.apply(bitblock::load_aligned(&cs.lo[7]));
     121
     122        H[0] = deletionAlgorithm.apply(bitblock::load_aligned(&cs.hi[0]));
     123        H[1] = deletionAlgorithm.apply(bitblock::load_aligned(&cs.hi[1]));
     124        H[2] = deletionAlgorithm.apply(bitblock::load_aligned(&cs.hi[2]));
     125        H[3] = deletionAlgorithm.apply(bitblock::load_aligned(&cs.hi[3]));
     126        H[4] = deletionAlgorithm.apply(bitblock::load_aligned(&cs.hi[4]));
     127        H[5] = deletionAlgorithm.apply(bitblock::load_aligned(&cs.hi[5]));
     128        H[6] = deletionAlgorithm.apply(bitblock::load_aligned(&cs.hi[6]));
     129        H[7] = deletionAlgorithm.apply(bitblock::load_aligned(&cs.hi[7]));
    171130
    172131        /* --------------------------------------------------------------------- */
     
    189148        XMLCh * const contentStreamOrdinal = contentStream;
    190149
    191         for (unsigned int i = 0; i < 8; i++)
    192         {
    193             ubitblock bl;
    194             ubitblock bh;
    195 
    196             #ifdef USE_UTF16_BIG_ENDIAN
    197             bl._128 = esimd<8>::mergel(U16l[i], U16h[i]);
    198             bh._128 = esimd<8>::mergeh(U16l[i], U16h[i]);
    199             #else
    200             bl._128 = esimd<8>::mergel(U16h[i], U16l[i]);
    201             bh._128 = esimd<8>::mergeh(U16h[i], U16l[i]);
    202             #endif
    203 
    204             bitblock::store_unaligned(bl._128, reinterpret_cast<BytePack *>(contentStream));
    205             contentStream += del._8[i << 1];
    206 
    207             bitblock::store_unaligned(bh._128, reinterpret_cast<BytePack *>(contentStream));
    208             contentStream += del._8[(i << 1) | 1];
    209         }
    210 
    211         ubitblock refMarkers;
    212         refMarkers._128 = bitblock::load_aligned(&cs.references);
    213         ubitblock stringEnds;
    214         stringEnds._128 = bitblock::load_aligned(&cs.delimiters);
    215 
    216         if (likely(bitblock::any(simd_or(stringEnds._128, refMarkers._128))))
     150        contentStream = streamCompressor.write(U16h, U16l, contentStream);
     151
     152
     153        /* --------------------------------------------------------------------- */
     154        /* CALCULATE DELIMITER POSITIONS
     155        /* --------------------------------------------------------------------- */
     156
     157        IntAlignedBitVector delimiters(bitblock::load_aligned(&cs.delimiters));
     158        const BitBlock refMarkers = bitblock::load_aligned(&cs.references);
     159
     160        if (likely(bitblock::any(simd_or(delimiters._b, refMarkers))))
    217161        {
    218162            // always shift the strings back up front (even if we don't have any)
    219             do_right8_shifts(stringEnds._128, shift1, shift2, shift4);
     163            delimiters._b = deletionAlgorithm.apply(delimiters._b);
    220164
    221165            /* --------------------------------------------------------------------- */
    222             /* CALCULATE PARTIAL SUM OF DELETED CHARACTERS
     166            /* HANDLE REFERENCE REPLACEMENTS
    223167            /* --------------------------------------------------------------------- */
    224 
    225             del._128 = simd<8>::sub(simd<8>::constant<8>(), del._128);
    226             del._128 = simd<8>::add(del._128, mvmd<8>::slli<1>(del._128));
    227             del._128 = simd<8>::add(del._128, mvmd<8>::slli<2>(del._128));
    228             del._128 = simd<8>::add(del._128, mvmd<8>::slli<4>(del._128));
    229             del._128 = simd<8>::add(del._128, mvmd<8>::slli<8>(del._128));
    230             del._128 = mvmd<8>::slli<1>(del._128);
    231 
    232             /* (i.e., if del._8 was initially { 0, 1, 2, 3, 4, ... } it will now be
    233                {0, 8, 15, 21, 26, 30, ... }) */
    234 
    235             /* --------------------------------------------------------------------- */
    236             /* HANDLE REF REPLACEMENTS
    237             /* --------------------------------------------------------------------- */
    238             if (unlikely(bitblock::any(refMarkers._128)))
    239             {
    240                 do_right8_shifts(refMarkers._128, shift1, shift2, shift4);
    241 
    242                 XMLStreamIterator referenceItr(refMarkers);
    243                 while (referenceItr.next())
     168            if (unlikely(bitblock::any(refMarkers)))
     169            {
     170                BitBlockIterator referenceItr(deletionAlgorithm.apply(refMarkers));
     171
     172                while (referenceItr.hasNext())
    244173                {
     174                    size_t pos = referenceItr.next();
    245175                    const gid_t refId = *referencePtr++;
    246 
    247176                    const XMLReplacementText & replacementText = (*fReferenceTable)[refId];
    248177
    249                     size_t pos = referenceItr.pos();
    250                     const size_t del_adj = del._8[pos >> 3];
    251                     if (replacementText.getType() < XMLReplacementText::GeneralEntity)
     178                    if (likely(replacementText.getType() < XMLReplacementText::GeneralEntity))
    252179                    {
    253180                        // direct subsitution of a predefined entity or character reference
    254                         pos -= del_adj;
     181                        pos = streamCompressor.partialMap(pos);
    255182                        if (unlikely(replacementText.getType() == XMLReplacementText::SurrogateCharacterReference))
    256183                        {
     
    266193                        // record the unresolved entity
    267194                        *generalEntityReferencePtr++ = refId;
    268                         // augment the string end stream by adding the reference position to it; this will
    269                         // allow the XMLParser (or XMLEntityParser) to stop on the reference and act accordingly.
    270                         #ifdef __ARCH_64
    271                         stringEnds._64[pos >> CONST_LOG_2(64)] |= (static_cast<uint64_t>(1) << (pos & 63));
    272                         #else
    273                         stringEnds._32[pos >> CONST_LOG_2(32)] |= (static_cast<uint32_t>(1) << (pos & 31));
    274                         #endif
     195
     196                        // augment the string delimiter stream by adding the reference position to it ...
     197                        delimiters.insert(pos);
     198
    275199                        // and overwrite the '&' with a 0xFFFE
    276                         pos -= del_adj;
    277                         contentStreamOrdinal[pos] = 0xFFFE; // MarkupType::Entity;
     200                        contentStreamOrdinal[streamCompressor.partialMap(pos)] = 0xFFFE; // MarkupType::Entity;
    278201                    }
    279202                }
     
    285208            // don't bother checking "bitblock::any(stringEnds)"; the register transfer cost
    286209            // will likely exceed its worth given that it'd almost always return true
    287             XMLStreamIterator stringItr(stringEnds);
    288             while (stringItr.next())
    289             {
    290                 const size_t pos = stringItr.pos() - del._8[stringItr.pos() >> 3];
    291                 *stringEndPtr++ = &contentStreamOrdinal[pos];
     210            BitBlockIterator stringItr(delimiters._b);
     211            while (stringItr.hasNext())
     212            {
     213                *stringEndPtr++ = &contentStreamOrdinal[streamCompressor.partialMap(stringItr.next())];
    292214            }
    293215
     
    300222            //   - could use 32-bit offsets only to reduce memory usage. what would be the cost of coverting them in the Parser?
    301223
     224
    302225        }
    303226    }
    304 
    305     // record the number of recursive references
    306     referenceCount = generalEntityReferencePtr - referenceStream;
    307227
    308228    // finalize the content stream char
    309229    *contentStream = 0xFFFF;
    310230    *stringEndPtr = contentStream;
    311     stringEndCount = stringEndPtr - stringEndStream;
    312 
    313     return contentStream;
     231
     232    // record the number of recursive references
     233    parser.fReferenceCount = generalEntityReferencePtr - parser.fReferenceStream.first();
     234    parser.fStringCount = stringEndPtr - parser.fStringEndStream.first();
     235    parser.fCursorEndPtr = contentStream;
    314236}
    315237
    316238// ---------------------------------------------------------------------------
    317 //  XMLUTF8CharacterSetAdapter: Implementation of the transcoder API
     239//  XMLUTF16CharacterSetAdapter: Implementation of the transcoder API
    318240// ---------------------------------------------------------------------------
    319241
     242#if defined(PRINT_DEBUG_MESSAGE) && !defined(PRINT_DEBUG_IGNORE_TRANSITION_STREAM_MESSAGES)
     243#define PRINT_TRANSITION_STREAM_MESSAGES
     244#endif
     245
    320246#define UTF_16_BUFFER_BLOCKS (BUFFER_BLOCKS / 2)
    321247
    322 XMLCh * XMLUTF16CharacterSetAdapter::parse
     248void XMLUTF16CharacterSetAdapter::parse
    323249(
    324250    const XMLByte * const               input
    325251    , const size_t              avail
    326252    , const bool                                noMore
    327     ,       XMLCh *             contentStream
    328     ,           gid_t *             symbolStream
    329     ,           size_t &            symbolCount
    330     ,           gid_t *             referenceStream
    331     ,           size_t &            referenceCount
    332     ,const XMLCh **             stringEndStream
    333     ,       size_t &            stringEndCount
    334     ,       size_t &            markupCount
     253    , XMLParser &               parser
    335254    ,           size_t &            bytesEaten
    336255)
     
    341260    BitBlock entityMarkerStream[UTF_16_BUFFER_BLOCKS] = {0};
    342261    BitBlock attValueSpanStream[UTF_16_BUFFER_BLOCKS] = {0};
    343     BitBlock deletionMaskStream[UTF_16_BUFFER_BLOCKS + 1] = {simd<1>::constant<1>(), 0};
     262    BitBlock deletionMaskStream[UTF_16_BUFFER_BLOCKS + 1] = {0};
     263    BitBlock delimiterStream[BUFFER_BLOCKS] = {0};
    344264    ContentInputStream contentInputStream[UTF_16_BUFFER_BLOCKS] = {0};
    345265   
     
    363283
    364284
    365         PopCounter<3> markupCounter;
     285    XMLLineColTracker lineColTracker(fLine, fColumn);
     286    PopCounter<3> markupCounter;
    366287
    367288    /// ----------------------------------------------------------------------------------------------------
     
    377298        parameters.XML_11 = simd<1>::constant<0>();
    378299    }
    379     memset(&errors, 0, sizeof(Errors));
     300    Array<Errors>::memzero(errors);
    380301
    381302    /// ----------------------------------------------------------------------------------------------------
     
    387308    const XMLByte * data = &input[fInternalOffset];
    388309
    389     #if defined(PRINT_DEBUG_MESSAGE) && !defined(PRINT_DEBUG_IGNORE_TRANSITION_STREAM_MESSAGES)
     310    #ifdef PRINT_TRANSITION_STREAM_MESSAGES
    390311    XMLByte DATA_BLOCK[66] = {'|', 0};
    391312    #endif
     
    393314    for (; count--; index++)
    394315    {
    395         #if defined(PRINT_DEBUG_MESSAGE) && !defined(PRINT_DEBUG_IGNORE_TRANSITION_STREAM_MESSAGES)
     316        #ifdef PRINT_TRANSITION_STREAM_MESSAGES
    396317        for (unsigned int scanOffset = 0; scanOffset < (BLOCK_SIZE * 2); scanOffset += 64)
    397318        {
     
    406327            }
    407328
    408             DEBUG_SYMBOL_MESSAGE("----------------------------------------------------------------------");
    409             DEBUG_SYMBOL_MESSAGE(
     329            DEBUG_MESSAGE("----------------------------------------------------------------------");
     330            DEBUG_MESSAGE(
    410331                 XERCES_STD_QUALIFIER setw(5) <<
    411332                 (tempOffset) <<
    412333                 XERCES_STD_QUALIFIER setw(0) <<
    413334                 DATA_BLOCK );
    414             DEBUG_SYMBOL_MESSAGE("----------------------------------------------------------------------");
     335            DEBUG_MESSAGE("----------------------------------------------------------------------");
    415336        }
    416337        #endif
     
    442363        bitblock::store_aligned(callouts.AttValSpan, attValueSpanStream + index);
    443364
    444 
    445         // update the line/column tracker
    446         fInternalLineColTracker.next(lex.LF, callouts.skipmask);
    447        // and the markup counter
     365        // store the data needed for the line/column tracker
     366        lineColTracker.write(index, lex.LF, callouts.skipmask);
     367
     368        // and the markup delimiters
     369        bitblock::store_aligned(callouts.MarkupDelimiters, delimiterStream + index);
    448370        markupCounter.tally(callouts.MarkupDelimiters);
     371
    449372        // scan for errors
    450         checkErrors(data, errors);
    451         // advance to the next block
    452         fInternalLineColTracker.advance();
     373        checkErrors(lineColTracker, index, data, errors);
    453374
    454375        data += (BLOCK_SIZE * 2);
     
    463384        const size_t advance = (avail - fInternalOffset) & ((BLOCK_SIZE * 2) - 1);
    464385
    465         #if defined(PRINT_DEBUG_MESSAGE) && !defined(PRINT_DEBUG_IGNORE_TRANSITION_STREAM_MESSAGES)
     386        #ifdef PRINT_TRANSITION_STREAM_MESSAGES
    466387        size_t remaining = advance;
    467388        for (unsigned int scanOffset = 0; scanOffset < (BLOCK_SIZE * 2); scanOffset += 64)
     
    482403            }
    483404
    484             DEBUG_SYMBOL_MESSAGE("----------------------------------------------------------------------");
    485             DEBUG_SYMBOL_MESSAGE(
     405            DEBUG_MESSAGE("----------------------------------------------------------------------");
     406            DEBUG_MESSAGE(
    486407                 XERCES_STD_QUALIFIER setw(5) <<
    487408                 (tempOffset) <<
    488409                 XERCES_STD_QUALIFIER setw(0) <<
    489410                 DATA_BLOCK );
    490             DEBUG_SYMBOL_MESSAGE("----------------------------------------------------------------------");
     411            DEBUG_MESSAGE("----------------------------------------------------------------------");
    491412        }
    492413        #endif
     
    511432        // write the deletion mask for the EM and CSG
    512433        bitblock::store_aligned(callouts.delmask, deletionMaskStream + count + 1);
    513 //          bitblock::store_aligned(simd_or(lex.LF, callouts.skipmask), &newLineOrSkipMaskStream[index]);
    514434
    515435        // merge the symbol start and end streams together
     
    520440        bitblock::store_aligned(callouts.AttValSpan, attValueSpanStream + count);
    521441
    522         // update the line/column tracker
    523         fInternalLineColTracker.next(lex.LF, callouts.skipmask);
    524        // and the markup counter
     442        // store the data needed for the line/column tracker
     443        lineColTracker.write(count, lex.LF, callouts.skipmask);
     444        // and the markup delimiters
     445        bitblock::store_aligned(callouts.MarkupDelimiters, delimiterStream + c