/*
Исходный код среды исполнения ПВТ-ОО.
Этот исходный код является частью проекта ПВТ-ОО.
Copyright © 2021 Малик Разработчик
Это свободная программа: вы можете перераспространять её и/или
изменять её на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
Эта программа распространяется в надежде, что она может быть полезна,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЁННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
общественной лицензии GNU.
Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<http://www.gnu.org/licenses/>.
*/
package avt.lang;
import avt.io.*;
public final class Package(/*Reflective*/Object)
{
public static Package get(String canonicalName) throws PackageNotFoundException {
Package result = find(canonicalName);
if(result == null)
{
throw new PackageNotFoundException("пакет не найден");
}
return result;
}
public static Package[] enumerate() {
int length = 1;
Package[] result = new Package[15];
for(Package current = (result[0] = boolean.class.ownedPackage).getNext(); current != null; current = current.getNext())
{
if(length == result.length)
{
Array.copy(result, 0, result = new Package[(length << 1) + 1], 0, length);
}
result[length++] = current;
}
if(length != result.length)
{
Array.copy(result, 0, result = new Package[length], 0, length);
}
return result;
}
package static Package find(String canonicalName) {
Package start = boolean.class.ownedPackage;
if(canonicalName == null || canonicalName.isEmpty()) return start;
for(Package current = start.getNext(); current != null; current = current.getNext())
{
if(canonicalName.equals(current.getCanonicalName())) return current;
}
return null;
}
private final int fldModifiers;
private final int fldCanonicalNameIndex;
private final int fldReserved28;
private final int fldReserved2C;
private final int fldTypesCount;
private final int fldReserved34;
private final int fldReserved38;
private final int fldReserved3C;
private final int fldTypesOffset;
private final int fldReserved44;
private final int fldReserved48;
private final int fldReserved4C;
private final long fldNextPackageOffset;
private int fldAddedTypesCount;
private int fldReserved5C;
private Class[] fldAddedTypes;
private String fldCanonicalName;
private () { }
public String toString() { return "package " + getCanonicalName(); }
public Class[] enumerateTypes() {
int count = fldTypesCount;
int length = 0;
Class[] result = new Class[count];
for(int index = 0; index < count; index++)
{
Class type = getType(index);
if(type.isArray())
{
Class componentType = type.componentType;
if(!componentType.isPrimitive() && componentType != Object.class) continue;
}
result[length++] = type;
}
if(length != count)
{
Array.copy(result, 0, result = new Class[length], 0, length);
}
return result;
}
public String[] enumerateResources() {
int length = 0;
String[] result = new String[15];
for(String prefix = getResourcePrefix(), int offset = prefix.length, ResourceEnumerator e = new ResourceEnumerator(); e.hasMoreResources(); e.nextResource())
{
String current = e.getName();
if(current != null && current.startsWith(prefix))
{
if(length == result.length)
{
Array.copy(result, 0, result = new String[(length << 1) + 1], 0, length);
}
result[length++] = current.substring(offset);
}
}
if(length != result.length)
{
Array.copy(result, 0, result = new String[length], 0, length);
}
return result;
}
public ByteReader openResource(String name) {
if(name == null)
{
throw new NullPointerException("аргумент name равен нулевой ссылке");
}
for(String prefix = getResourcePrefix(), int offset = prefix.length, int length = offset + name.length, ResourceEnumerator e = new ResourceEnumerator(); e.hasMoreResources(); e.nextResource())
{
String current = e.getName();
if(current != null && current.length == length && current.startsWith(prefix) && current.endsWith(name))
{
return new ByteArrayInputStream(e.getData());
}
}
return null;
}
public String simpleName { read = getSimpleName }
public String canonicalName { read = getCanonicalName }
package void addType(Class type) {
int count = fldAddedTypesCount;
Class[] types = fldAddedTypes;
if(types == null)
{
fldAddedTypes = types = new Class[15];
}
else if(count == types.length)
{
Array.copy(types, 0, fldAddedTypes = types = new Class[(count << 1) + 1], 0, count);
}
types[count++] = type;
fldAddedTypesCount = count;
}
package Class getAddedArrayType(Class componentType) {
for(int count = fldAddedTypesCount, Class[] types = fldAddedTypes, int index = 0; index < count; index++)
{
Class type = types[index];
if(type.isArray() && type.componentType == componentType) return type;
}
return null;
}
package Class findType(String simpleName) {
if(simpleName != null) for(int count = fldTypesCount, int index = 0; index < count; index++)
{
Class type = getType(index);
if(simpleName.equals(type.simpleName)) return type;
}
return null;
}
private native Package getNext();
private native Class getType(int index);
private String getSimpleName() {
String canonicalName = getCanonicalName();
return canonicalName.substring(canonicalName.lastIndexOf('.') + 1);
}
private String getCanonicalName() {
String result = fldCanonicalName;
return result != null ? result : fldCanonicalName = String.getConstant(fldCanonicalNameIndex);
}
private String getResourcePrefix() { return (new StringBuilder() + '/' + getCanonicalName().replace('.', '/') + '/').toString(); }
}
final class ResourceEnumerator(Object)
{
private int fldDataLength;
private int fldNameLength;
private long fldResourcePointer;
public () { initialize(); }
public native void nextResource();
public boolean hasMoreResources() { return fldNameLength > 0; }
public byte[] getData() {
if(fldNameLength <= 0) return null;
long dataPointer = fldResourcePointer + fldNameLength + 2L;
dataPointer += (-dataPointer & 3L) + 4L;
byte[] result = null;
try
{
result = (byte[]) byte[].class.newArrayAt(dataPointer, fldDataLength);
}
catch(Exception e)
{
e.printStackTrace();
}
return result;
}
public String getName() {
if(fldNameLength <= 0) return null;
long namePointer = fldResourcePointer + 2L;
byte[] result = null;
try
{
result = (byte[]) byte[].class.newArrayAt(namePointer, fldNameLength);
}
catch(Exception e)
{
e.printStackTrace();
}
return result == null ? null : new String(result);
}
private native void initialize();
}