StreamFormatManager.avt

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

/*
    Исходный код среды исполнения ПВТ-ОО.

    Этот исходный код является частью проекта ПВТ-ОО.

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

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

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

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

package platform.independent.streamformat;

import avt.util.*;

public service StreamFormatManager(Object)
{
    public static MIMETypeInfo[] supportedMIMETypes() {
        Hashtable storage = new Hashtable();
        for(String packprefix = "platform.independent.streamformat.", int packprefixlen = packprefix.length, Package[] packs = Package.enumerate(), int packidx = packs.length; packidx-- > 0; )
        {
            Package pack = packs[packidx];
            String name = pack.canonicalName;
            if(name != null && name.startsWith(packprefix))
            {
                int pos = (name = name.substring(packprefixlen)).indexOf('.');
                if(pos >= 0) name = name.substring(0, pos);
                for(Class[] types = pack.enumerateTypes(), int typeidx = types.length; typeidx-- > 0; )
                {
                    Class type = types[typeidx];
                    if(!type.isArray() && !type.isStruct() && !type.isPrimitive() && !type.isAbstract() && type.visibility >= Class.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() + name + '/' + toSubtype(type.simpleName)).toString();
                            boolean[] supported = (boolean[]) storage[mimeType];
                            if(supported == null)
                            {
                                storage[mimeType] = new boolean[] { isDecoder, isEncoder, isCodec };
                            } else
                            {
                                supported[0] |= isDecoder;
                                supported[1] |= isEncoder;
                                supported[2] |= isCodec;
                            }
                        }
                    }
                }
            }
        }
        MIMETypeInfo[] result = new MIMETypeInfo[storage.length];
        for(MapEnumeration e = storage.enumerateKeys(), int i = 0; e.hasMoreElements(); i++)
        {
            String mimeType = (String) e.nextElement();
            boolean[] supported = (boolean[]) e.value();
            result[i] = new MIMETypeInfo(mimeType, supported[0], supported[1], supported[2]);
        }
        return result;
    }

    public static MIMETypeInfo getMIMETypeInfo(String mimeType) {
        if(mimeType == null)
        {
            throw new NullPointerException("аргумент mimeType равен нулевой ссылке");
        }
        int pos = mimeType.indexOf('/');
        if(pos < 0)
        {
            throw new IllegalArgumentException("аргумент mimeType не содержит символ \'/\'");
        }
        boolean isCodec = false;
        boolean isEncoder = false;
        boolean isDecoder = false;
        for(String packprefix = (new StringBuilder() + "platform.independent.streamformat." + mimeType.substring(0, pos) + '.').toString(), int packprefixlen = packprefix.length, 
            String subtype = mimeType.substring(pos + 1), Package[] packs = Package.enumerate(), int packidx = packs.length; packidx-- > 0; )
        {
            Package pack = packs[packidx];
            String name = pack.canonicalName;
            if(name != null && name.startsWith(packprefix)) for(Class[] types = pack.enumerateTypes(), int typeidx = types.length; typeidx-- > 0; )
            {
                Class type = types[typeidx];
                if(!type.isArray() && !type.isStruct() && !type.isPrimitive() && !type.isAbstract() && type.visibility >= Class.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 StreamFormatNotFoundException, DataConverterNotFoundException, InstantiationException, IllegalAccessException {
        if(mimeType == null)
        {
            throw new NullPointerException("аргумент mimeType равен нулевой ссылке");
        }
        int pos = mimeType.indexOf('/');
        if(pos < 0)
        {
            throw new IllegalArgumentException("аргумент mimeType не содержит символ \'/\'");
        }
        boolean isCodec = false;
        boolean isEncoder = false;
        boolean isDecoder = false;
        for(String packprefix = (new StringBuilder() + "platform.independent.streamformat." + mimeType.substring(0, pos) + '.').toString(), int packprefixlen = packprefix.length, 
            String subtype = mimeType.substring(pos + 1), Package[] packs = Package.enumerate(), int packidx = packs.length; packidx-- > 0; )
        {
            Package pack = packs[packidx];
            String name = pack.canonicalName;
            if(name != null && name.startsWith(packprefix)) for(Class[] types = pack.enumerateTypes(), int typeidx = types.length; typeidx-- > 0; )
            {
                Class type = types[typeidx];
                if(!type.isArray() && !type.isStruct() && !type.isPrimitive() && !type.isAbstract() && type.visibility >= Class.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("формат потока данных не найден");
        }
        throw new DataConverterNotFoundException("кодек для формата потока данных не найден") { mimeType = mimeType };
    }

    public static DataEncoder createEncoder(String mimeType) throws StreamFormatNotFoundException, DataConverterNotFoundException, InstantiationException, IllegalAccessException {
        if(mimeType == null)
        {
            throw new NullPointerException("аргумент mimeType равен нулевой ссылке");
        }
        int pos = mimeType.indexOf('/');
        if(pos < 0)
        {
            throw new IllegalArgumentException("аргумент mimeType не содержит символ \'/\'");
        }
        boolean isCodec = false;
        boolean isEncoder = false;
        boolean isDecoder = false;
        for(String packprefix = (new StringBuilder() + "platform.independent.streamformat." + mimeType.substring(0, pos) + '.').toString(), int packprefixlen = packprefix.length, 
            String subtype = mimeType.substring(pos + 1), Package[] packs = Package.enumerate(), int packidx = packs.length; packidx-- > 0; )
        {
            Package pack = packs[packidx];
            String name = pack.canonicalName;
            if(name != null && name.startsWith(packprefix)) for(Class[] types = pack.enumerateTypes(), int typeidx = types.length; typeidx-- > 0; )
            {
                Class type = types[typeidx];
                if(!type.isArray() && !type.isStruct() && !type.isPrimitive() && !type.isAbstract() && type.visibility >= Class.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("формат потока данных не найден");
        }
        throw new DataConverterNotFoundException("кодер для формата потока данных не найден") { mimeType = mimeType };
    }

    public static DataDecoder createDecoder(String mimeType) throws StreamFormatNotFoundException, DataConverterNotFoundException, InstantiationException, IllegalAccessException {
        if(mimeType == null)
        {
            throw new NullPointerException("аргумент mimeType равен нулевой ссылке");
        }
        int pos = mimeType.indexOf('/');
        if(pos < 0)
        {
            throw new IllegalArgumentException("аргумент mimeType не содержит символ \'/\'");
        }
        boolean isCodec = false;
        boolean isEncoder = false;
        boolean isDecoder = false;
        for(String packprefix = (new StringBuilder() + "platform.independent.streamformat." + mimeType.substring(0, pos) + '.').toString(), int packprefixlen = packprefix.length, 
            String subtype = mimeType.substring(pos + 1), Package[] packs = Package.enumerate(), int packidx = packs.length; packidx-- > 0; )
        {
            Package pack = packs[packidx];
            String name = pack.canonicalName;
            if(name != null && name.startsWith(packprefix)) for(Class[] types = pack.enumerateTypes(), int typeidx = types.length; typeidx-- > 0; )
            {
                Class type = types[typeidx];
                if(!type.isArray() && !type.isStruct() && !type.isPrimitive() && !type.isAbstract() && type.visibility >= Class.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("формат потока данных не найден");
        }
        throw new DataConverterNotFoundException("декодер для формата потока данных не найден") { mimeType = mimeType };
    }

    private static String toSubtype(String simpleName) {
        StringBuilder result = new StringBuilder();
        for(int length = simpleName.length, String previous = null, int beginIndex = 0; beginIndex < length; )
        {
            int endIndex = beginIndex + 1;
            for(char c; endIndex < length && ((c = simpleName[endIndex]) >= '0' && c <= '9' || c >= 'a' && c <= '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(previous != null && !"Plus".equals(previous) && !"_".equals(previous)) result + '-';
                    result + word.toLowerCase();
                }
            }
            previous = word;
            beginIndex = endIndex;
        }
        return result.toString();
    }
}