actual/packages/node-libofx/OpenSP-1.5.2/include/CharMap.h
2022-04-28 22:44:38 -04:00

229 lines
5.4 KiB
C++

// Copyright (c) 1997 James Clark, 2000 Matthias Clasen
// See the file COPYING for copying permission.
#ifndef CharMap_INCLUDED
#define CharMap_INCLUDED 1
#include "types.h"
#include "Resource.h"
#ifdef SP_NAMESPACE
namespace SP_NAMESPACE {
#endif
#ifdef SP_MULTI_BYTE
class CharMapBits {
public:
// 21 bits are enough for the UTF-16 range
enum { level0 = 5, level1 = 8, level2 = 4, level3 = 4 };
enum {
planes = (1 << CharMapBits::level0) ,
pagesPerPlane = (1 << CharMapBits::level1),
columnsPerPage = (1 << CharMapBits::level2),
cellsPerColumn = (1 << CharMapBits::level3),
planeSize = (1 << (CharMapBits::level1 + CharMapBits::level2 + CharMapBits::level3)),
pageSize = (1 << (CharMapBits::level2 + CharMapBits::level3)),
columnSize = (1 << CharMapBits::level3)
};
static size_t planeIndex(size_t c) {
return (c >> (CharMapBits::level1 + CharMapBits::level2 + CharMapBits::level3));
}
static size_t pageIndex(size_t c) {
return ((c >> (CharMapBits::level2 + CharMapBits::level3)) & (pagesPerPlane - 1));
}
static size_t columnIndex(size_t c) {
return ((c >> CharMapBits::level3) & (columnsPerPage - 1));
}
static size_t cellIndex(size_t c) {
return (c & (cellsPerColumn - 1));
}
static size_t maxInPlane(size_t c) {
return (c | (planeSize - 1));
}
static size_t maxInPage(size_t c) {
return (c | (pageSize - 1));
}
static size_t maxInColumn(size_t c) {
return (c | (columnSize - 1));
}
};
#if 0
// These are defines rather than static member functions of CharMapBits,
// since gcc chokes on them in array allocations.
#define planes (1 << CharMapBits::level0)
#define pagesPerPlane (1 << CharMapBits::level1)
#define columnsPerPage (1 << CharMapBits::level2)
#define cellsPerColumn (1 << CharMapBits::level3)
#define planeSize (1 << (CharMapBits::level1 + CharMapBits::level2 + CharMapBits::level3))
#define pageSize (1 << (CharMapBits::level2 + CharMapBits::level3))
#define columnSize (1 << CharMapBits::level3)
#define planeIndex(c) ((c) >> (CharMapBits::level1 + CharMapBits::level2 + CharMapBits::level3))
#define pageIndex(c) (((c) >> (CharMapBits::level2 + CharMapBits::level3)) & (pagesPerPlane - 1))
#define columnIndex(c) (((c) >> CharMapBits::level3) & (columnsPerPage - 1))
#define cellIndex(c) ((c) & (cellsPerColumn - 1))
#define maxInPlane(c) ((c) | (planeSize - 1))
#define maxInPage(c) ((c) | (pageSize - 1))
#define maxInColumn(c) ((c) | (columnSize - 1))
#endif
template<class T>
class CharMapColumn {
public:
CharMapColumn();
CharMapColumn(const CharMapColumn<T> &);
void operator=(const CharMapColumn<T> &);
~CharMapColumn();
T *values;
T value;
};
template<class T>
class CharMapPage {
public:
CharMapPage();
CharMapPage(const CharMapPage<T> &);
void operator=(const CharMapPage<T> &);
~CharMapPage();
void swap(CharMapPage<T> &);
CharMapColumn<T> *values;
T value;
};
template<class T>
class CharMapPlane {
public:
CharMapPlane();
CharMapPlane(const CharMapPlane<T> &);
void operator=(const CharMapPlane<T> &);
~CharMapPlane();
void swap(CharMapPlane<T> &);
CharMapPage<T> *values;
T value;
};
#endif /* SP_MULTI_BYTE */
template<class T>
class CharMap {
public:
CharMap();
CharMap(T);
T operator[](Char) const;
T getRange(Char from, Char &to) const;
void swap(CharMap<T> &);
void setChar(Char, T);
void setRange(Char from, Char to, T val);
void setAll(T);
private:
#ifdef SP_MULTI_BYTE
CharMapPlane<T> values_[CharMapBits::planes];
T lo_[256];
#else
T values_[256];
#endif
};
template<class T>
class CharMapResource : public CharMap<T>, public Resource {
public:
CharMapResource() { }
CharMapResource(T t) : CharMap<T>(t) { }
};
#ifdef SP_MULTI_BYTE
template<class T>
inline
T CharMap<T>::operator[](Char c) const
{
if (c < 256)
return lo_[c];
const CharMapPlane<T> &pl = values_[CharMapBits::planeIndex(c)];
if (pl.values) {
const CharMapPage<T> &pg = pl.values[CharMapBits::pageIndex(c)];
if (pg.values) {
const CharMapColumn<T> &column = pg.values[CharMapBits::columnIndex(c)];
if (column.values)
return column.values[CharMapBits::cellIndex(c)];
else
return column.value;
}
else
return pg.value;
}
else
return pl.value;
}
template<class T>
inline
T CharMap<T>::getRange(Char c, Char &max) const
{
if (c < 256) {
max = c;
return lo_[c];
}
const CharMapPlane<T> &pl = values_[CharMapBits::planeIndex(c)];
if (pl.values) {
const CharMapPage<T> &pg = pl.values[CharMapBits::pageIndex(c)];
if (pg.values) {
const CharMapColumn<T> &column = pg.values[CharMapBits::columnIndex(c)];
if (column.values) {
max = c;
return column.values[CharMapBits::cellIndex(c)];
}
else {
max = CharMapBits::maxInColumn(c);
return column.value;
}
}
else {
max = CharMapBits::maxInPage(c);
return pg.value;
}
}
else {
max = CharMapBits::maxInPlane(c);
return pl.value;
}
}
#else
template<class T>
inline
T CharMap<T>::operator[](Char c) const
{
return values_[c];
}
template<class T>
inline
T CharMap<T>::getRange(Char c, Char &max) const
{
max = c;
return values_[c];
}
template<class T>
inline
void CharMap<T>::setChar(Char c, T val)
{
values_[c] = val;
}
#endif
#ifdef SP_NAMESPACE
}
#endif
#endif /* not CharMap_INCLUDED */
#ifdef SP_DEFINE_TEMPLATES
#include "CharMap.cxx"
#endif