Esempio n. 1
0
void LvlArchive::Load()
{
    // Read and validate the header
    LvlHeader header;
    ReadHeader(header);
    if (header.iNull1 != 0 || header.iNull2 != 0 || header.iMagic != MakeType('I', 'n', 'd', 'x'))
    {
        LOG_ERROR("Invalid LVL header");
        throw InvalidLvl("Invalid header");
    }

    // Read the file records
    std::vector<FileRecord> recs;
    recs.reserve(header.iNumFiles);
    for (auto i = 0u; i < header.iNumFiles; i++)
    {
        FileRecord rec;
        mStream.ReadBytes(&rec.iFileNameBytes[0], sizeof(rec.iFileNameBytes));
        mStream.ReadUInt32(rec.iStartSector);
        mStream.ReadUInt32(rec.iNumSectors);
        mStream.ReadUInt32(rec.iFileSize);
        recs.emplace_back(rec);
    }

    for (const auto& rec : recs)
    {
        mFiles.emplace_back(std::make_unique<File>(mStream, rec));
    }

    LOG_INFO("Loaded LVL '" << mStream.Name() << "' with " << header.iNumFiles << " files");
}
Esempio n. 2
0
void LvlArchive::File::LoadChunks(Stream& stream, Uint32 fileSize)
{
    while (stream.Pos() < stream.Pos() + fileSize)
    {
        ChunkHeader header;
        stream.ReadUInt32(header.iSize);
        stream.ReadUInt32(header.iRefCount);
        stream.ReadUInt32(header.iType);
        stream.ReadUInt32(header.iId);

        const bool isEnd = header.iType == MakeType('E', 'n', 'd', '!');
        const Uint32 kChunkHeaderSize = sizeof(Uint32) * 4;

        if (!isEnd)
        {
            mChunks.emplace_back(std::make_unique<FileChunk>(stream, header.iType, header.iId, header.iSize - kChunkHeaderSize));
        }

        // Only move to next if the block isn't empty
        if (header.iSize)
        {
            stream.Seek((stream.Pos() + header.iSize) - kChunkHeaderSize);
        }

        // End! block, stop reading any more blocks
        if (isEnd)
        {
            break;
        }
    }
}
boost::optional<SemanticError*> PropertySymbolTable::addMethod(Type* returntype, vector<pair<string, TypeArray*> >* segments_arguments, int flags) {
	string name = getSymbolNameOf(segments_arguments);

	if(properties.count(name)) {
		string temp = "duplicate method signature is " + name;
		return boost::optional<SemanticError*>(new SemanticError(MULTIPLE_METHOD_DEFINITION, temp));
	}

	if(flags & PROPERTY_ABSTRACT) {
		abstract = true;
	}

	Type* method = MakeType(TYPE_LAMBDA);
	method->typedata.lambda.returntype = copyType(returntype);

	TypeArray* conglomerate = MakeTypeArray();
	for(vector<pair<string, TypeArray*> >::iterator it = segments_arguments->begin(); it != segments_arguments->end(); ++it) {
		int i;
		for(i = 0; i < it->second->typecount; i++)
			AddTypeToTypeArray(copyType(it->second->types[i]), conglomerate);
	}

	method->typedata.lambda.arguments = conglomerate;

	ObjectProperty* prop = new ObjectProperty;
	prop->flags = flags;
	prop->type = method;
	prop->casing = getCasingNameOf(segments_arguments);
	prop->address = name;

	properties[name] = prop;

	return boost::optional<SemanticError*>();
}
Esempio n. 4
0
bool TypeAnalyzer::isException(Type* type) {
	Type* exception = MakeType(TYPE_CLASS);
	exception->typedata._class.classname = strdup("Exception");
	bool ret = isASubtypeOfB(type, exception);
	freeType(exception);
	return ret;
}
Esempio n. 5
0
bool TypeAnalyzer::isAutoboxedType(Type* type, Type** boxed) {
	if(type->type == TYPE_MATCHALL) return false;

	// shouldn't be here...throw exception?
	if(type->type == TYPE_UNUSABLE) return false;

	// need to return a List<T>
	if(type->arrayed) {
		*boxed = MakeType(TYPE_CLASS);
		Type* loweredtype = copyType(type);
		loweredtype->arrayed--;
		(*boxed)->typedata._class.classname = strdup("List");
		(*boxed)->typedata._class.parameters = MakeTypeArray();
		AddTypeToTypeArray(loweredtype, (*boxed)->typedata._class.parameters);
		return true;
	}

	// need to return a generic autoboxed type according to arguments/return
	if(type->type == TYPE_LAMBDA) {
		*boxed = MakeType(TYPE_CLASS);
		(*boxed)->typedata._class.classname = strdup("lambda");
		return true;
	}

	// shouldn't ever get here,..unless I decide to make, say, T?.exists() and/or T?.applyIfExists(fn(T))
	if(type->optional) return false;

	if(isPrimitiveTypeBool(type)) {
		*boxed = MakeType(TYPE_CLASS);
		(*boxed)->typedata._class.classname = strdup("Bool");
		return true;
	}

	if(isPrimitiveTypeText(type)) {
		*boxed = MakeType(TYPE_CLASS);
		(*boxed)->typedata._class.classname = strdup("Text");
		return true;
	}

	if(isPrimitiveTypeNum(type)) {
		*boxed = MakeType(TYPE_CLASS);
		(*boxed)->typedata._class.classname = strdup("Num");
		return true;
	}

	return false;
}
Type* PropertySymbolTable::getAsType() {
	Type* ret = MakeType(TYPE_CLASS);
	ret->typedata._class.classname = strdup(classname.c_str());
	if(getParameters().size()) {
		ret->typedata._class.parameters = MakeTypeArray();
		for(vector<Type*>::const_iterator it = getParameters().begin(); it != getParameters().end(); ++it) {
			AddTypeToTypeArray(*it, ret->typedata._class.parameters);
		}
	}

	return ret;
}
boost::optional<SemanticError*> PropertySymbolTable::addProvision(Type* provided, int flags) {
	string name = analyzer->getNameForType(provided) + "<-";
	if(provided->specialty != NULL) name += provided->specialty;

	if(properties.count(name)) {
		string temp = "duplicate provisoning is " + name;
		return boost::optional<SemanticError*>(new SemanticError(DUPLICATE_PROPERTY_DEFINITION, temp));
	}

	Type* method = MakeType(TYPE_LAMBDA);
	method->typedata.lambda.returntype = copyType(provided);

	method->typedata.lambda.arguments = MakeTypeArray(); //TODO injections with curried ctors or arguments!

	ObjectProperty* prop = new ObjectProperty;
	prop->type = method;
	prop->casing = name;
	prop->address = name;
	prop->flags = flags;

	properties[name] = prop;
	return boost::optional<SemanticError*>();
}