// 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 < 256; i++) lo_[i] = dflt; for (size_t i = 0; i < CharMapBits::planes; i++) values_[i].value = dflt; } template void CharMap::setAll(T val) { for (size_t i = 0; i < 256; i++) lo_[i] = val; for (size_t i = 0; i < CharMapBits::planes; i++) { values_[i].value = val; delete [] values_[i].values; values_[i].values = 0; } } template void CharMap::swap(CharMap &map) { for (size_t i = 0; i < 256; i++) { T tem(lo_[i]); lo_[i] = map.lo_[i]; map.lo_[i] = tem; } for (size_t i = 0; i < CharMapBits::planes; i++) values_[i].swap(map.values_[i]); } template void CharMap::setChar(Char c, T val) { if (c < 256) { lo_[c] = val; return; } CharMapPlane &pl = values_[CharMapBits::planeIndex(c)]; if (pl.values) { CharMapPage &pg = pl.values[CharMapBits::pageIndex(c)]; if (pg.values) { CharMapColumn &column = pg.values[CharMapBits::columnIndex(c)]; if (column.values) column.values[CharMapBits::cellIndex(c)] = val; else if (val != column.value) { column.values = new T[CharMapBits::columnSize]; for (size_t i = 0; i < CharMapBits::columnSize; i++) column.values[i] = column.value; column.values[CharMapBits::cellIndex(c)] = val; } } else if (val != pg.value) { pg.values = new CharMapColumn[CharMapBits::columnsPerPage]; for (size_t i = 0; i < CharMapBits::columnsPerPage; i++) pg.values[i].value = pg.value; CharMapColumn &column = pg.values[CharMapBits::columnIndex(c)]; column.values = new T[CharMapBits::cellsPerColumn]; for (size_t i = 0; i < CharMapBits::cellsPerColumn; i++) column.values[i] = column.value; column.values[CharMapBits::cellIndex(c)] = val; } } else if (val != pl.value) { pl.values = new CharMapPage[CharMapBits::pagesPerPlane]; for (size_t i = 0; i < CharMapBits::pagesPerPlane; i++) pl.values[i].value = pl.value; CharMapPage &page = pl.values[CharMapBits::pageIndex(c)]; page.values = new CharMapColumn[CharMapBits::columnsPerPage]; for (size_t i = 0; i < CharMapBits::columnsPerPage; i++) page.values[i].value = page.value; CharMapColumn &column = page.values[CharMapBits::columnIndex(c)]; column.values = new T[CharMapBits::cellsPerColumn]; for (size_t i = 0; i < CharMapBits::cellsPerColumn; i++) column.values[i] = column.value; column.values[CharMapBits::cellIndex(c)] = val; } } template void CharMap::setRange(Char from, Char to, T val) { for (; from < 256; from++) { lo_[from] = val; if (from == to) return; } do { if ((from & (CharMapBits::columnSize - 1)) == 0 && to - from >= CharMapBits::columnSize - 1) { if ((from & (CharMapBits::pageSize - 1)) == 0 && to - from >= CharMapBits::pageSize - 1) { if ((from & (CharMapBits::planeSize - 1)) == 0 && to - from >= CharMapBits::planeSize - 1) { // Set a complete plane. CharMapPlane &pl = values_[CharMapBits::planeIndex(from)]; pl.value = val; delete [] pl.values; pl.values = 0; from += CharMapBits::planeSize - 1; } else { // Set a complete page. CharMapPlane &pl = values_[CharMapBits::planeIndex(from)]; if (pl.values) { CharMapPage &pg = pl.values[CharMapBits::pageIndex(from)]; pg.value = val; delete [] pg.values; pg.values = 0; } else if (val != pl.value) { // split the plane pl.values = new CharMapPage[CharMapBits::pagesPerPlane]; for (size_t i = 0; i < CharMapBits::pagesPerPlane; i++) pl.values[i].value = pl.value; CharMapPage &page = pl.values[CharMapBits::pageIndex(from)]; page.value = val; } from += CharMapBits::pageSize - 1; } } else { // Set a complete column. CharMapPlane &pl = values_[CharMapBits::planeIndex(from)]; if (pl.values) { CharMapPage &pg = pl.values[CharMapBits::pageIndex(from)]; if (pg.values) { CharMapColumn &column = pg.values[CharMapBits::columnIndex(from)]; column.value = val; delete [] column.values; column.values = 0; } else if (val != pg.value) { // split the page pg.values = new CharMapColumn[CharMapBits::columnsPerPage]; for (size_t i = 0; i < CharMapBits::columnsPerPage; i++) pg.values[i].value = pg.value; CharMapColumn &column = pg.values[CharMapBits::columnIndex(from)]; column.value = val; } } else if (val != pl.value) { // split the plane pl.values = new CharMapPage[CharMapBits::pagesPerPlane]; for (size_t i = 0; i < CharMapBits::pagesPerPlane; i++) pl.values[i].value = pl.value; CharMapPage &pg = pl.values[CharMapBits::pageIndex(from)]; pg.value = val; // split the page pg.values = new CharMapColumn[CharMapBits::columnsPerPage]; for (size_t i = 0; i < CharMapBits::columnsPerPage; i++) pg.values[i].value = pg.value; CharMapColumn &column = pg.values[CharMapBits::columnIndex(from)]; column.value = val; } from += CharMapBits::columnSize - 1; } } else setChar(from, val); } while (from++ != to); } template CharMapPlane::CharMapPlane() : values(0) { } template CharMapPlane::CharMapPlane(const CharMapPlane &pl) { if (pl.values) { values = new CharMapPage[CharMapBits::pagesPerPlane]; for (size_t i = 0; i < CharMapBits::pagesPerPlane; i++) values[i] = pl.values[i]; } else { value = pl.value; values = 0; } } template void CharMapPlane::operator=(const CharMapPlane &pl) { if (pl.values) { if (!values) values = new CharMapPage[CharMapBits::pagesPerPlane]; for (size_t i = 0; i < CharMapBits::pagesPerPlane; i++) values[i] = pl.values[i]; } else { if (values) { delete [] values; values = 0; } value = pl.value; } } template CharMapPlane::~CharMapPlane() { delete [] values; } template void CharMapPlane::swap(CharMapPlane &pl) { { CharMapPage *tem = values; values = pl.values; pl.values = tem; } { T tem(value); value = pl.value; pl.value = tem; } } template CharMapPage::CharMapPage() : values(0) { } template CharMapPage::CharMapPage(const CharMapPage &pg) { if (pg.values) { values = new CharMapColumn[CharMapBits::columnsPerPage]; for (size_t i = 0; i < CharMapBits::columnsPerPage; 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[CharMapBits::columnsPerPage]; for (size_t i = 0; i < CharMapBits::columnsPerPage; 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[CharMapBits::cellsPerColumn]; for (size_t i = 0; i < CharMapBits::cellsPerColumn; 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[CharMapBits::cellsPerColumn]; for (size_t i = 0; i < CharMapBits::cellsPerColumn; 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 */