All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.epam.deltix.util.security.EntitlementIDComposer Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2023 EPAM Systems, Inc
 *
 * See the NOTICE file distributed with this work for additional information
 * regarding copyright ownership. 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.
 */
package com.epam.deltix.util.security;

import com.epam.deltix.util.lang.StringUtils;
import com.epam.deltix.containers.BinaryArray;

public class EntitlementIDComposer implements EntitlementID {
    
    protected final int         entriesOffset;

    protected BinaryArray       content;
    protected boolean           isNull;

    public EntitlementIDComposer() {
        this(0);
    }

    public EntitlementIDComposer(int entriesOffset) {
        this.entriesOffset = entriesOffset;
        reset();
    }

    @SuppressWarnings("unchecked")
    public T reset() {
        resetContent();
        setSafely(content, entriesOffset, (byte) 0);
        
        isNull = true;
        
        return (T) this; // unchecked
    }

    public T appendEntry(byte[] content) {
        return appendEntry(content, 0, content.length);
    }
    
    @SuppressWarnings("unchecked")
    public T appendEntry(byte[] content, int offset, int length) {        
        setSafely(this.content, entriesOffset, (byte) (numberOfEntries() + 1));
        
        this.content.append((byte) length);
        this.content.append(content, offset, length);
        
        isNull = false;
        
        return (T) this; // unchecked
    }

    @SuppressWarnings("unchecked")
    public T appendAllEntries(T from) {
        setSafely(this.content, entriesOffset, (byte) (numberOfEntries() + from.numberOfEntries()));

        final int sizeToAdd = from.content.size() - from.entriesOffset - 1;
        content.append(from.content.toByteArray(), from.entriesOffset + 1, sizeToAdd);

        isNull = false;
        
        return (T) this; // unchecked
    }
    
    @Override
    public boolean isNull() {
        return isNull;
    }

    @Override
    public int numberOfEntries() {
        return content != null ? content.get(entriesOffset) & 0xFF : 0;
    }

    @Override
    public byte[] content() {
        return content != null ? content.toByteArray() : null;
    }

    @Override
    public int size() {
        return content != null ? content.size() : 0;
    }
    
    @Override
    public int entryOffset(int entryIndex) {
        if (entryIndex >= numberOfEntries()) {
            throw new IndexOutOfBoundsException();
        }
        return getEntryContentIndex(entryIndex) + 1;
    }

    @Override
    public int entryLength(int entryIndex) {
        if (entryIndex >= numberOfEntries()) {
            throw new IndexOutOfBoundsException();
        }        
        return content.get(getEntryContentIndex(entryIndex)) & 0xFF;
    }

    @Override
    public String toString() {
        final StringBuilder result = new StringBuilder(getClass().getSimpleName()).append(':');
        if (isNull) {
            result.append("NULL");
        } else {
            result.append("entriesOffset=").append(Integer.toString(entriesOffset)).append(',');
            result.append("numberOfEntries=").append(Integer.toString(numberOfEntries()));
            result.append('[');
            result.append(StringUtils.toHex(content.toByteArray(), 0, entriesOffset));
            result.append('^');
            result.append(StringUtils.toHex(content.toByteArray(), entriesOffset, content.size() - entriesOffset));
            result.append(']');
        }
        return result.toString();
    }    
    
    protected void resetContent() {
        if (content != null) {
            content.clear();
        } else {
            content = new BinaryArray();
        }        
    }
    
    private int getEntryContentIndex(int entryIndex) {
        int result = entriesOffset + 1;
        // some unrolling
        switch (entryIndex) {
            case 0:
                break;
            case 1:
                result = result + (content.get(result) & 0xFF) + 1;
                break;
            case 2:
                result = result + (content.get(result) & 0xFF) + 1;
                result = result + (content.get(result) & 0xFF) + 1;
                break;
            case 3:
                result = result + (content.get(result) & 0xFF) + 1;
                result = result + (content.get(result) & 0xFF) + 1;
                result = result + (content.get(result) & 0xFF) + 1;
                break;
            case 4:
                result = result + (content.get(result) & 0xFF) + 1;
                result = result + (content.get(result) & 0xFF) + 1;
                result = result + (content.get(result) & 0xFF) + 1;
                result = result + (content.get(result) & 0xFF) + 1;
                break;
            case 5:
                result = result + (content.get(result) & 0xFF) + 1;
                result = result + (content.get(result) & 0xFF) + 1;
                result = result + (content.get(result) & 0xFF) + 1;
                result = result + (content.get(result) & 0xFF) + 1;
                result = result + (content.get(result) & 0xFF) + 1;
                break;
            default:
                result = result + (content.get(result) & 0xFF) + 1;
                result = result + (content.get(result) & 0xFF) + 1;
                result = result + (content.get(result) & 0xFF) + 1;
                result = result + (content.get(result) & 0xFF) + 1;
                result = result + (content.get(result) & 0xFF) + 1;
                result = result + (content.get(result) & 0xFF) + 1;
                for (int entry = 7; entry <= entryIndex; entry++) {
                    result = result + (content.get(result) & 0xFF) + 1;
                }
                break;
        }
        
        return result;        
    }

    protected static void setSafely(BinaryArray content, int index, byte value) {
        int overhead = index - content.size();

        for (int i = 0; i <= overhead; i++)
            content.append((byte)0);

        content.set(index, value);

//        final int d = content.size() - index;
//        if (d <= 0) {
//            for (int i = 0; i <= -d - 1; i++) {
//                content.add(i, (byte) 0);
//            }
//            content.add(-d, value);
//            return;
//        }
//        content.set(index, value);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy