StreamFormatManager.avt

Переключить прокрутку окна
Загрузить этот исходный код

/*
    Реализация среды исполнения языка программирования
    Объектно-ориентированный продвинутый векторный транслятор

    Copyright © 2021, 2024 Малик Разработчик

    Это свободная программа: вы можете перераспространять ее и/или изменять
    ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
    в каком она была опубликована Фондом свободного программного обеспечения;
    либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.

    Эта программа распространяется в надежде, что она будет полезной,
    но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
    или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
    общественной лицензии GNU.

    Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
    вместе с этой программой. Если это не так, см.
    <https://www.gnu.org/licenses/>.
*/

package platform.independent.streamformat;

import avt.lang.table.*;

public service StreamFormatManager(Object)
{
    public static MIMETypeInfo[] supportedMIMETypes() {
        int storageLength = 0;
        KeyValueTable storage = new KeyValueTable();
        for(String packPrefix = "platform.independent.streamformat.", int packPrefixLength = packPrefix.length, Package[] packs = Package.enumerate(), int packIndex = packs.length; packIndex-- > 0; )
        {
            Package pack = packs[packIndex];
            String packName = pack.canonicalName;
            if(packName != null && packName.startsWith(packPrefix))
            {
                int dotPosition = (packName = packName.substring(packPrefixLength)).indexOf('.');
                if(dotPosition >= 0) packName = packName.substring(0, dotPosition);
                for(Class[] types = pack.enumerateTypes(), int typeIndex = types.length; typeIndex-- > 0; )
                {
                    Class type = types[typeIndex];
                    if((type.isClass() && !type.isArray() || type.isService()) && !type.isAbstract() && type.visibility >= ReflectiveObject.PUBLIC)
                    {
                        boolean isCodec = DataCodec.class.isAssignableFrom(type);
                        boolean isEncoder = DataEncoder.class.isAssignableFrom(type);
                        boolean isDecoder = DataDecoder.class.isAssignableFrom(type);
                        if(isCodec || isEncoder || isDecoder)
                        {
                            String mimeType = (new StringBuilder() + packName + '/' + toSubtype(type.simpleName)).toString();
                            boolean[] supported = (boolean[]) storage[mimeType];
                            if(supported == null)
                            {
                                storage[mimeType] = new boolean[] { isDecoder, isEncoder, isCodec };
                                storageLength++;
                            } else
                            {
                                supported[0] |= isDecoder;
                                supported[1] |= isEncoder;
                                supported[2] |= isCodec;
                            }
                        }
                    }
                }
            }
        }
        MIMETypeInfo[] mimeTypes = new MIMETypeInfo[storageLength];
        Enumeration kve = storage.enumerate();
        if(kve != null)
        {
            int mimeTypeIndex = 0;
            do
            {
                String mimeType = (String) kve.key;
                boolean[] supported = (boolean[]) kve.value;
                mimeTypes[mimeTypeIndex++] = new MIMETypeInfo(mimeType, supported[0], supported[1], supported[2]);
            } while(kve.findNext());
        }
        return mimeTypes;
    }

    public static MIMETypeInfo getMIMETypeInfo(String mimeType) {
        if(mimeType == null)
        {
            throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "mimeType" }));
        }
        int solidusPosition = mimeType.indexOf('/');
        if(solidusPosition < 0)
        {
            throw new IllegalArgumentException(String.format(package.getResourceString("illegal-argument.mime-type.solidus"), new Object[] { "mimeType" }));
        }
        boolean isCodec = false;
        boolean isEncoder = false;
        boolean isDecoder = false;
        for(
            String packPrefix = (new StringBuilder() + "platform.independent.streamformat." + mimeType.substring(0, solidusPosition) + '.').toString(), int packPrefixLength = packPrefix.length,
            String subtype = mimeType.substring(solidusPosition + 1), Package[] packs = Package.enumerate(), int packIndex = packs.length; packIndex-- > 0;
        )
        {
            Package pack = packs[packIndex];
            String packName = pack.canonicalName;
            if(packName != null && packName.startsWith(packPrefix)) for(Class[] types = pack.enumerateTypes(), int typeIndex = types.length; typeIndex-- > 0; )
            {
                Class type = types[typeIndex];
                if((type.isClass() && !type.isArray() || type.isService()) && !type.isAbstract() && type.visibility >= ReflectiveObject.PUBLIC && toSubtype(type.simpleName).equals(subtype))
                {
                    isCodec |= DataCodec.class.isAssignableFrom(type);
                    isEncoder |= DataEncoder.class.isAssignableFrom(type);
                    isDecoder |= DataDecoder.class.isAssignableFrom(type);
                }
            }
        }
        return !(isCodec || isEncoder || isDecoder) ? null : new MIMETypeInfo(mimeType, isDecoder, isEncoder, isCodec);
    }

    public static DataCodec createCodec(String mimeType) throws DataConverterNotFoundException, StreamFormatNotFoundException, InstantiationException, IllegalAccessException {
        if(mimeType == null)
        {
            throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "mimeType" }));
        }
        int solidusPosition = mimeType.indexOf('/');
        if(solidusPosition < 0)
        {
            throw new IllegalArgumentException(String.format(package.getResourceString("illegal-argument.mime-type.solidus"), new Object[] { "mimeType" }));
        }
        boolean isCodec = false;
        boolean isEncoder = false;
        boolean isDecoder = false;
        for(
            String packPrefix = (new StringBuilder() + "platform.independent.streamformat." + mimeType.substring(0, solidusPosition) + '.').toString(), int packPrefixLength = packPrefix.length,
            String subtype = mimeType.substring(solidusPosition + 1), Package[] packs = Package.enumerate(), int packIndex = packs.length; packIndex-- > 0;
        )
        {
            Package pack = packs[packIndex];
            String packName = pack.canonicalName;
            if(packName != null && packName.startsWith(packPrefix)) for(Class[] types = pack.enumerateTypes(), int typeIndex = types.length; typeIndex-- > 0; )
            {
                Class type = types[typeIndex];
                if((type.isClass() && !type.isArray() || type.isService()) && !type.isAbstract() && type.visibility >= ReflectiveObject.PUBLIC && toSubtype(type.simpleName).equals(subtype))
                {
                    isCodec |= DataCodec.class.isAssignableFrom(type);
                    isEncoder |= DataEncoder.class.isAssignableFrom(type);
                    isDecoder |= DataDecoder.class.isAssignableFrom(type);
                    if(isCodec) return (DataCodec) type.newInstance();
                }
            }
        }
        if(!(isCodec || isEncoder || isDecoder))
        {
            throw new StreamFormatNotFoundException(String.format(package.getResourceString("not-found.stream-format"), new Object[] { mimeType }));
        }
        throw new DataConverterNotFoundException(package.getResourceString("not-found.data-converter.codec")) { mimeType = mimeType };
    }

    public static DataEncoder createEncoder(String mimeType) throws DataConverterNotFoundException, StreamFormatNotFoundException, InstantiationException, IllegalAccessException {
        if(mimeType == null)
        {
            throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "mimeType" }));
        }
        int solidusPosition = mimeType.indexOf('/');
        if(solidusPosition < 0)
        {
            throw new IllegalArgumentException(String.format(package.getResourceString("illegal-argument.mime-type.solidus"), new Object[] { "mimeType" }));
        }
        boolean isCodec = false;
        boolean isEncoder = false;
        boolean isDecoder = false;
        for(
            String packPrefix = (new StringBuilder() + "platform.independent.streamformat." + mimeType.substring(0, solidusPosition) + '.').toString(), int packPrefixLength = packPrefix.length,
            String subtype = mimeType.substring(solidusPosition + 1), Package[] packs = Package.enumerate(), int packIndex = packs.length; packIndex-- > 0;
        )
        {
            Package pack = packs[packIndex];
            String packName = pack.canonicalName;
            if(packName != null && packName.startsWith(packPrefix)) for(Class[] types = pack.enumerateTypes(), int typeIndex = types.length; typeIndex-- > 0; )
            {
                Class type = types[typeIndex];
                if((type.isClass() && !type.isArray() || type.isService()) && !type.isAbstract() && type.visibility >= ReflectiveObject.PUBLIC && toSubtype(type.simpleName).equals(subtype))
                {
                    isCodec |= DataCodec.class.isAssignableFrom(type);
                    isEncoder |= DataEncoder.class.isAssignableFrom(type);
                    isDecoder |= DataDecoder.class.isAssignableFrom(type);
                    if(isEncoder) return (DataEncoder) type.newInstance();
                }
            }
        }
        if(!(isCodec || isEncoder || isDecoder))
        {
            throw new StreamFormatNotFoundException(String.format(package.getResourceString("not-found.stream-format"), new Object[] { mimeType }));
        }
        throw new DataConverterNotFoundException(package.getResourceString("not-found.data-converter.encoder")) { mimeType = mimeType };
    }

    public static DataDecoder createDecoder(String mimeType) throws DataConverterNotFoundException, StreamFormatNotFoundException, InstantiationException, IllegalAccessException {
        if(mimeType == null)
        {
            throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "mimeType" }));
        }
        int solidusPosition = mimeType.indexOf('/');
        if(solidusPosition < 0)
        {
            throw new IllegalArgumentException(String.format(package.getResourceString("illegal-argument.mime-type.solidus"), new Object[] { "mimeType" }));
        }
        boolean isCodec = false;
        boolean isEncoder = false;
        boolean isDecoder = false;
        for(
            String packPrefix = (new StringBuilder() + "platform.independent.streamformat." + mimeType.substring(0, solidusPosition) + '.').toString(), int packPrefixLength = packPrefix.length,
            String subtype = mimeType.substring(solidusPosition + 1), Package[] packs = Package.enumerate(), int packIndex = packs.length; packIndex-- > 0;
        )
        {
            Package pack = packs[packIndex];
            String packName = pack.canonicalName;
            if(packName != null && packName.startsWith(packPrefix)) for(Class[] types = pack.enumerateTypes(), int typeIndex = types.length; typeIndex-- > 0; )
            {
                Class type = types[typeIndex];
                if((type.isClass() && !type.isArray() || type.isService()) && !type.isAbstract() && type.visibility >= ReflectiveObject.PUBLIC && toSubtype(type.simpleName).equals(subtype))
                {
                    isCodec |= DataCodec.class.isAssignableFrom(type);
                    isEncoder |= DataEncoder.class.isAssignableFrom(type);
                    isDecoder |= DataDecoder.class.isAssignableFrom(type);
                    if(isDecoder) return (DataDecoder) type.newInstance();
                }
            }
        }
        if(!(isCodec || isEncoder || isDecoder))
        {
            throw new StreamFormatNotFoundException(String.format(package.getResourceString("not-found.stream-format"), new Object[] { mimeType }));
        }
        throw new DataConverterNotFoundException(package.getResourceString("not-found.data-converter.decoder")) { mimeType = mimeType };
    }

    private static String toSubtype(String simpleName) {
        StringBuilder result = new StringBuilder();
        for(int length = simpleName.length, String prev = null, int beginIndex = 0; beginIndex < length; )
        {
            int endIndex = beginIndex + 1;
            for(char chr; endIndex < length && ((chr = simpleName[endIndex]) >= '0' && chr <= '9' || chr >= 'a' && chr <= 'z'); endIndex++);
            String word = simpleName.substring(beginIndex, endIndex);
            if(!("Encoder".equals(word) || "Decoder".equals(word) || "Codec".equals(word)))
            {
                if("Plus".equals(word))
                {
                    result + '+';
                }
                else if("_".equals(word))
                {
                    result + '.';
                }
                else
                {
                    if(prev != null && !("Plus".equals(prev) || "_".equals(prev))) result + '-';
                    result + word.toLowerCase();
                }
            }
            prev = word;
            beginIndex = endIndex;
        }
        return result.toString();
    }
}