Пример #1
0
bool FileLoader::openFile(const char* filename, bool write, bool caching /*= false*/)
{
	if(write) {
		m_file = fopen(filename, "wb");
		if(m_file) {
			uint32_t version = 0;
			writeData(&version, sizeof(version), false);
			return true;
		}
		else{
			m_lastError = ERROR_CAN_NOT_CREATE;
			return false;
		}
	}
	else {
		m_file = fopen(filename, "rb");
		if(m_file){
			uint32_t version;
			fread(&version, sizeof(version), 1, m_file);
			if(version > 0){
				fclose(m_file);
				m_file = NULL;
				m_lastError = ERROR_INVALID_FILE_VERSION;
				return false;
			}
			else{
				if(caching){
					m_use_cache = true;
					fseek(m_file, 0, SEEK_END);
					int file_size = ftell(m_file);
					m_cache_size = std::min(32768, std::max(file_size/20, 8192)) & ~0x1FFF;
				}
				
				//parse nodes
				if(safeSeek(4)){
					delete m_root;
					m_root = new NodeStruct();
					m_root->start = 4;
					int byte;
					if(safeSeek(4) && readByte(byte) && byte == NODE_START){
						bool ret = parseNode(m_root);
						return ret;
					}
					else{
						return false;
					}
				}
				else{
					m_lastError = ERROR_INVALID_FORMAT;
					return false;
				}
			}
		}
		else{
			m_lastError = ERROR_CAN_NOT_OPEN;
			return false;
		}
	}
}
Пример #2
0
bool FileLoader::openFile(const char* filename, const char* accept_identifier)
{
	m_file = fopen(filename, "rb");
	if (!m_file) {
		m_lastError = ERROR_CAN_NOT_OPEN;
		return false;
	}

	char identifier[4];
	if (fread(identifier, 1, 4, m_file) < 4) {
		fclose(m_file);
		m_file = nullptr;
		m_lastError = ERROR_EOF;
		return false;
	}

	// The first four bytes must either match the accept identifier or be 0x00000000 (wildcard)
	if (memcmp(identifier, accept_identifier, 4) != 0 && memcmp(identifier, "\0\0\0\0", 4) != 0) {
		fclose(m_file);
		m_file = nullptr;
		m_lastError = ERROR_INVALID_FILE_VERSION;
		return false;
	}

	fseek(m_file, 0, SEEK_END);
	int32_t file_size = ftell(m_file);
	m_cache_size = std::min<uint32_t>(32768, std::max<uint32_t>(file_size / 20, 8192)) & ~0x1FFF;

	if (!safeSeek(4)) {
		m_lastError = ERROR_INVALID_FORMAT;
		return false;
	}

	delete m_root;
	m_root = new NodeStruct();
	m_root->start = 4;

	int32_t byte;
	if (safeSeek(4) && readByte(byte) && byte == NODE_START) {
		return parseNode(m_root);
	}

	return false;
}
Пример #3
0
bool FileLoader::parseNode(NODE node)
{
	int32_t byte;
	int32_t pos;
	NODE currentNode = node;
	while(1)
	{
		//read node type
		if(readByte(byte))
		{
			currentNode->type = byte;
			bool setPropsSize = false;
			while(1)
			{
				//search child and next node
				if(readByte(byte))
				{
					if(byte == NODE_START)
					{
						//child node start
						if(safeTell(pos))
						{
							NODE childNode = new NodeStruct();
							childNode->start = pos;
							setPropsSize = true;
							currentNode->propsSize = pos - currentNode->start - 2;
							currentNode->child = childNode;
							if(!parseNode(childNode))
								return false;
						}
						else
							return false;
					}
					else if(byte == NODE_END)
					{
						//current node end
						if(!setPropsSize)
						{
							if(safeTell(pos))
								currentNode->propsSize = pos - currentNode->start - 2;
							else
								return false;
						}

						if(readByte(byte))
						{
							if(byte == NODE_START)
							{
								//starts next node
								if(safeTell(pos))
								{
									NODE nextNode = new NodeStruct();
									nextNode->start = pos;
									currentNode->next = nextNode;
									currentNode = nextNode;
									break;
								}
								else
									return false;
							}
							else if(byte == NODE_END)
							{
								//up 1 level and move 1 position back
								if(safeTell(pos) && safeSeek(pos))
									return true;
								else
									return false;
							}
							else
							{
								//wrong format
								m_lastError = ERROR_INVALID_FORMAT;
								return false;
							}
						}
						else
						{
							//end of file?
							return true;
						}
					}
					else if(byte == ESCAPE_CHAR)
					{
						if(!readByte(byte))
							return false;
					}
				}
				else
					return false;
			}
		}
		else
			return false;
	}
}
Пример #4
0
bool FileLoader::parseNode(NODE node)
{
	int32_t byte, pos;
	NODE currentNode = node;

	while (readByte(byte)) {
		currentNode->type = byte;
		bool setPropsSize = false;

		while (true) {
			if (!readByte(byte)) {
				return false;
			}

			bool skipNode = false;

			switch (byte) {
				case NODE_START: {
					//child node start
					if (!safeTell(pos)) {
						return false;
					}

					NODE childNode = new NodeStruct();
					childNode->start = pos;
					currentNode->propsSize = pos - currentNode->start - 2;
					currentNode->child = childNode;

					setPropsSize = true;

					if (!parseNode(childNode)) {
						return false;
					}

					break;
				}

				case NODE_END: {
					//current node end
					if (!setPropsSize) {
						if (!safeTell(pos)) {
							return false;
						}

						currentNode->propsSize = pos - currentNode->start - 2;
					}

					if (!readByte(byte)) {
						return true;
					}

					switch (byte) {
						case NODE_START: {
							//starts next node
							if (!safeTell(pos)) {
								return false;
							}

							skipNode = true;
							NODE nextNode = new NodeStruct();
							nextNode->start = pos;
							currentNode->next = nextNode;
							currentNode = nextNode;
							break;
						}

						case NODE_END:
							return safeTell(pos) && safeSeek(pos);

						default:
							m_lastError = ERROR_INVALID_FORMAT;
							return false;
					}

					break;
				}

				case ESCAPE_CHAR: {
					if (!readByte(byte)) {
						return false;
					}

					break;
				}

				default:
					break;
			}

			if (skipNode) {
				break;
			}
		}
	}
	return false;
}
Пример #5
0
bool FileLoader::openFile(const char* filename, const char* accept_identifier, bool write, bool caching /*= false*/)
{
	if(write)
	{
		m_file = fopen(filename, "wb");
		if(!m_file)
		{
			m_lastError = ERROR_CAN_NOT_CREATE;
			return false;
		}

		uint32_t version = 0;
		writeData(&version, sizeof(version), false);
		return true;
	}

	m_file = fopen(filename, "rb");
	if(!m_file)
	{
		m_lastError = ERROR_CAN_NOT_OPEN;
		return false;
	}

	char identifier[4];
	if(fread(identifier, 1, 4, m_file) < 4)
	{
		fclose(m_file);
		m_file = NULL;
		m_lastError = ERROR_EOF;
		return false;
	}

	// The first four bytes must either match the accept identifier or be 0x00000000 (wildcard)
	if(memcmp(identifier, accept_identifier, 4) != 0 && memcmp(identifier, "\0\0\0\0", 4) != 0)
	{
		fclose(m_file);
		m_file = NULL;
		m_lastError = ERROR_INVALID_FILE_VERSION;
		return false;
	}

	if(caching)
	{
		m_use_cache = true;
		fseek(m_file, 0, SEEK_END);
		int32_t file_size = ftell(m_file);
		m_cache_size = std::min(32768, std::max(file_size/20, 8192)) & ~0x1FFF;
	}

	if(!safeSeek(4))
	{
		m_lastError = ERROR_INVALID_FORMAT;
		return false;
	}

	delete m_root;
	m_root = new NodeStruct();
	m_root->start = 4;

	int32_t byte;
	if(safeSeek(4) && readByte(byte) && byte == NODE_START)
		return parseNode(m_root);

	return false;
}