111 lines
2.8 KiB
C
111 lines
2.8 KiB
C
/*
|
|
* Copyright (C) 2014-2019 Muhammad Tayyab Akram
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include <SBConfig.h>
|
|
|
|
#include "SBBase.h"
|
|
#include "BidiChain.h"
|
|
|
|
SB_INTERNAL void BidiChainInitialize(BidiChainRef chain,
|
|
SBBidiType *types, SBLevel *levels, BidiLink *links)
|
|
{
|
|
chain->types = types;
|
|
chain->levels = levels;
|
|
chain->links = links;
|
|
chain->roller = 0;
|
|
chain->last = 0;
|
|
|
|
/* Make first link empty. */
|
|
chain->types[0] = SBBidiTypeNil;
|
|
chain->levels[0] = SBLevelInvalid;
|
|
chain->links[0] = BidiLinkNone;
|
|
}
|
|
|
|
SB_INTERNAL void BidiChainAdd(BidiChainRef chain, SBBidiType type, SBUInteger length)
|
|
{
|
|
BidiLink last = chain->last;
|
|
BidiLink current = last + (SBUInt32)length;
|
|
|
|
chain->types[current] = type;
|
|
chain->links[current] = chain->roller;
|
|
|
|
chain->links[last] = current;
|
|
chain->last = current;
|
|
}
|
|
|
|
SB_INTERNAL SBBoolean BidiChainIsSingle(BidiChainRef chain, BidiLink link)
|
|
{
|
|
BidiLink next = chain->links[link];
|
|
|
|
/* Check the type of in between code units. */
|
|
while (++link != next) {
|
|
if (chain->types[link] != SBBidiTypeBN) {
|
|
return SBFalse;
|
|
}
|
|
}
|
|
|
|
return SBTrue;
|
|
}
|
|
|
|
SB_INTERNAL SBBidiType BidiChainGetType(BidiChainRef chain, BidiLink link)
|
|
{
|
|
return chain->types[link];
|
|
}
|
|
|
|
SB_INTERNAL void BidiChainSetType(BidiChainRef chain, BidiLink link, SBBidiType type)
|
|
{
|
|
chain->types[link] = type;
|
|
}
|
|
|
|
SB_INTERNAL SBLevel BidiChainGetLevel(BidiChainRef chain, BidiLink link)
|
|
{
|
|
return chain->levels[link];
|
|
}
|
|
|
|
SB_INTERNAL void BidiChainSetLevel(BidiChainRef chain, BidiLink link, SBLevel level)
|
|
{
|
|
chain->levels[link] = level;
|
|
}
|
|
|
|
SB_INTERNAL BidiLink BidiChainGetNext(BidiChainRef chain, BidiLink link)
|
|
{
|
|
return chain->links[link];
|
|
}
|
|
|
|
SB_INTERNAL void BidiChainSetNext(BidiChainRef chain, BidiLink link, BidiLink next)
|
|
{
|
|
chain->links[link] = next;
|
|
}
|
|
|
|
SB_INTERNAL void BidiChainAbandonNext(BidiChainRef chain, BidiLink link)
|
|
{
|
|
BidiLink next = chain->links[link];
|
|
BidiLink limit = chain->links[next];
|
|
|
|
chain->links[link] = limit;
|
|
}
|
|
|
|
SB_INTERNAL SBBoolean BidiChainMergeIfEqual(BidiChainRef chain, BidiLink first, BidiLink second)
|
|
{
|
|
if (chain->types[first] == chain->types[second]
|
|
&& chain->levels[first] == chain->levels[second]) {
|
|
chain->links[first] = chain->links[second];
|
|
return SBTrue;
|
|
}
|
|
|
|
return SBFalse;
|
|
}
|