Пример #1
0
 /**
  * @brief
  *  Advance the input cursor by one character.
  * @remark
  *  If the file is was not opened, end of the input was reached or an error was encountered,
  *  before a call to this method, the call immediatly returns, not observably modifying the
  *  state of this object or the file.
  */
 virtual void advance()
 {
     // (1) If an error or the end of the input was encountered ...
     if (_current == Traits::error() || _current == Traits::endOfInput())
     {
         // ... do nothing.
         return;
     }
     // (2) If the backing VFS file is not opened ...
     if (!_file)
     {
         // ... raise an error.
         _current = Traits::error();
         return;
     }
     // (3) Otherwise: Read a single Byte.
     uint8_t byte;
     size_t size = vfs_read(&byte, 1, 1, _file);
     if (1 != size)
     {
         if (vfs_error(_file))
         {
             _current = Traits::error();
             return;
         }
         else if (vfs_eof(_file))
         {
             _current = Traits::endOfInput();
             return;
         }
         else
         {
             ostringstream message;
             message << __FILE__ << ":" << __LINE__ << ": "
                     << "inconsistent state of file object  of file `" << this->getFileName() << "`";
             throw runtime_error(message.str());
         }
     }
     // (4) Verify that it is a Byte the represents the starting Byte of a UTF-8 character sequence of length 1.
     if (byte > 0x7F)
     {
         _current = Traits::error();
         return;
     }
     // (5) Verify that it is not the zero terminator.
     if ('\0' == byte)
     {
         _current = Traits::error();
         return;
     }
     // (6) Propage the Byte to an extended character and store it.
     _current = (typename Traits::ExtendedType)byte;
 }
Пример #2
0
void vfs_mount(const char* dir)
{
	if (dir == NULL)
	{
		vfs_error("Mount directory is NULL\n");
		return;
	}

	char path[VFS_MOUNT_PATH_MAX];
	strcpy(path, dir);
	size_t pathlen = strlen(path);

	if (pathlen == 0)
	{
		vfs_error("Mount directory is of length 0\n");
		return;
	}

	if (path[pathlen - 1] == '\\' || path[pathlen - 1] == '/')
	{
		path[pathlen - 1] = '\0';
	}

	char** filenames = stb_readdir_recursive(path, NULL);

	if (filenames == NULL)
	{
		vfs_error("Could not read directory: %s\n", path);
		return;
	}

	int num_new_files = stb_arr_len(filenames);
	for (int i = 0; i < num_new_files; i++)
	{
		struct vfs_file new_file;
		strcpy(new_file.name, filenames[i]);
		strcpy(new_file.simplename, filenames[i] + strlen(path) + 1);

		int replaced = 0;
		for (int j = 0; j < vfs_global->file_count; j++)
		{
			if (strcmp(vfs_global->file_table[j].simplename, new_file.simplename) == 0)
			{
				stb_fclose(vfs_global->file_table[j].file, 0);
				free(vfs_global->file_table[j].data);

				strcpy(vfs_global->file_table[j].name, new_file.name);
				vfs_global->file_table[j].file = stb_fopen(vfs_global->file_table[j].name, "rb");
				vfs_global->file_table[j].lastChange = stb_ftimestamp(vfs_global->file_table[j].name);
				vfs_global->file_table[j].size = stb_filelen(vfs_global->file_table[j].file);
				vfs_global->file_table[j].data = malloc(vfs_global->file_table[j].size);
				fread(vfs_global->file_table[j].data, 1, vfs_global->file_table[j].size, vfs_global->file_table[j].file);
				stb_fclose(vfs_global->file_table[i].file, 0);

				replaced = 1;
				break;
			}
		}

		if (!replaced)
		{
			new_file.read_callbacks = 0;
			new_file.file = stb_fopen(new_file.name, "rb");
			new_file.lastChange = stb_ftimestamp(new_file.name);
			new_file.size = stb_filelen(new_file.file);
			new_file.data = malloc(new_file.size);
			fread(new_file.data, 1, new_file.size, new_file.file);
			stb_fclose(new_file.file, 0);

			vfs_global->file_table[vfs_global->file_count] = new_file;
			vfs_global->file_count++;
		}
	}
}