// Copyright (c) 1997 James Clark // See the file COPYING for copying permission. #ifndef CharMap_DEF_INCLUDED #define CharMap_DEF_INCLUDED 1 #ifdef SP_NAMESPACE namespace SP_NAMESPACE { #endif #ifdef SP_MULTI_BYTE template CharMap::CharMap() { } template CharMap::CharMap(T dflt) { for (size_t i = 0; i < (1 << CharMapBits::level1); i++) pages_[i].value = dflt; } template void CharMap::setAll(T val) { for (size_t i = 0; i < (1 << CharMapBits::level1); i++) { pages_[i].value = val; delete [] pages_[i].values; pages_[i].values = 0; } } template void CharMap::swap(CharMap &map) { for (size_t i = 0; i < (1 << CharMapBits::level1); i++) pages_[i].swap(map.pages_[i]); } template void CharMap::setChar(Char c, T val) { CharMapPage &pg = pages_[c >> (CharMapBits::level2 + CharMapBits::level3)]; if (pg.values) { CharMapColumn &column = pg.values[(c >> CharMapBits::level3) & ((1 << CharMapBits::level2) - 1)]; if (column.values) column.values[c & ((1 << CharMapBits::level3) - 1)] = val; else if (val != column.value) { column.values = new T[1 << CharMapBits::level3]; for (size_t i = 0; i < (1 << CharMapBits::level3); i++) column.values[i] = column.value; column.values[c & ((1 << CharMapBits::level3) - 1)] = val; } } else if (val != pg.value) { pg.values = new CharMapColumn[1 << CharMapBits::level2]; for (size_t i = 0; i < (1 << CharMapBits::level2); i++) pg.values[i].value = pg.value; CharMapColumn &column = pg.values[(c >> CharMapBits::level3) & ((1 << CharMapBits::level2) - 1)]; column.values = new T[1 << CharMapBits::level3]; for (size_t i = 0; i < (1 << CharMapBits::level3); i++) column.values[i] = column.value; column.values[c & ((1 << CharMapBits::level3) - 1)] = val; } } template void CharMap::setRange(Char from, Char to, T val) { do { if ((from & ((1 << CharMapBits::level3) - 1)) == 0 && to - from >= (1 << CharMapBits::level3) - 1) { if ((from & ((1 << (CharMapBits::level2 + CharMapBits::level3)) - 1)) == 0 && to - from >= (1 << (CharMapBits::level2 + CharMapBits::level3)) - 1) { // Set a complete page. CharMapPage &pg = pages_[from >> (CharMapBits::level2 + CharMapBits::level3)]; pg.value = val; delete [] pg.values; pg.values = 0; from += (1 << (CharMapBits::level2 + CharMapBits::level3)) - 1; } else { // Set a complete column. CharMapPage &pg = pages_[from >> (CharMapBits::level2 + CharMapBits::level3)]; if (pg.values) { CharMapColumn &column = pg.values[(from >> CharMapBits::level3) & ((1 << CharMapBits::level2) - 1)]; column.value = val; delete [] column.values; column.values = 0; } else if (val != pg.value) { // split the page pg.values = new CharMapColumn[1 << CharMapBits::level2]; for (size_t i = 0; i < (1 << CharMapBits::level2); i++) pg.values[i].value = pg.value; CharMapColumn &column = pg.values[(from >> CharMapBits::level3) & ((1 << CharMapBits::level2) - 1)]; column.value = val; } from += (1 << CharMapBits::level2) - 1; } } else setChar(from, val); } while (from++ != to); } template CharMapPage::CharMapPage() : values(0) { } template CharMapPage::CharMapPage(const CharMapPage &pg) { if (pg.values) { values = new CharMapColumn[1 << CharMapBits::level2]; for (size_t i = 0; i < (1 << CharMapBits::level2); i++) values[i] = pg.values[i]; } else { value = pg.value; values = 0; } } template void CharMapPage::operator=(const CharMapPage &pg) { if (pg.values) { if (!values) values = new CharMapColumn[1 << CharMapBits::level2]; for (size_t i = 0; i < (1 << CharMapBits::level2); i++) values[i] = pg.values[i]; } else { if (values) { delete [] values; values = 0; } value = pg.value; } } template CharMapPage::~CharMapPage() { delete [] values; } template void CharMapPage::swap(CharMapPage &pg) { { CharMapColumn *tem = values; values = pg.values; pg.values = tem; } { T tem(value); value = pg.value; pg.value = tem; } } template CharMapColumn::CharMapColumn() : values(0) { } template CharMapColumn::CharMapColumn(const CharMapColumn &col) { if (col.values) { values = new T[1 << CharMapBits::level3]; for (size_t i = 0; i < (1 << CharMapBits::level3); i++) values[i] = col.values[i]; } else { values = 0; value = col.value; } } template void CharMapColumn::operator=(const CharMapColumn &col) { if (col.values) { if (!values) values = new T[1 << CharMapBits::level3]; for (size_t i = 0; i < (1 << CharMapBits::level3); i++) values[i] = col.values[i]; } else { if (values) { delete [] values; values = 0; } value = col.value; } } template CharMapColumn::~CharMapColumn() { delete [] values; } #else /* not SP_MULTI_BYTE */ template CharMap::CharMap() { } template CharMap::CharMap(T dflt) { for (int i = 0; i < 256; i++) values_[i] = dflt; } template void CharMap::setAll(T val) { for (size_t i = 0; i < 256; i++) values_[i] = val; } template void CharMap::setRange(Char from, Char to, T val) { do { values_[from] = val; } while (from++ != to); } template void CharMap::swap(CharMap &map) { for (size_t i = 0; i < 256; i++) { T tem(values_[i]); values_[i] = map.values_[i]; map.values_[i] = tem; } } #endif /* not SP_MULTI_BYTE */ #ifdef SP_NAMESPACE } #endif #endif /* not CharMap_DEF_INCLUDED */