Пример #1
0
void commands_ns::DiskInfo(FileSystem *fs, int argc, char *argv[], std::ostream& out){	
	if (argc != 0) {
		out << "Неправильное количество параметров" << std::endl;
		return;
	}
	//размеры файлов даны в байтах
	size_t totalUsedSpace = 0;
	size_t fileSystemSize = fs->GetMaxSize();
	FileIterator* fileIterator = fs->GetIterator();
	
	while(fileIterator->HasNext()){
		fileIterator->Next();
		FileDescriptor* fileDescriptor = fileIterator->GetFileDescriptor();
		totalUsedSpace += fileDescriptor->GetSize();
	}

	size_t freeDiskSpace = fileSystemSize - totalUsedSpace;
	double ratio = (double)freeDiskSpace/fileSystemSize; 
	
	out << "Сведения о диске:" << std::endl;
	out << "Наименование: " << fs->GetTomName() << std::endl;
	out << "Размер свободного места: " << freeDiskSpace << " б (" << ratio*100 << "%)" << std::endl;
	out << "Максимальный объем: " << fileSystemSize << " б" << std::endl;

}
Пример #2
0
void LinkedFile<T>::indexLoad()
{
	FileIterator<T>* ite = this->getIterator();
	
	FILE_OFFSET inFileOffset = ite->getNextOffset();
	
	IndexedElement* lastElem = this->firstElem;
	
	while (ite->moveNext()) {
		Element<T>* current = ite->getCurrent();
		
		IndexedElement* elem = current->getIndexedElement();
		elem->inFileOffset = inFileOffset;
		elem->previous = lastElem;
		elem->next = NULL;
		
		// List
		lastElem->next = elem;
		lastElem = elem;
		
		this->indexAdd(current->key, elem);
		
		inFileOffset = ite->getNextOffset();
	}
	
	delete ite;
}
Пример #3
0
int File::findChildren(FileFinder& finder, vector<File*>& results, bool recursive,
		bool archiveEntries) const
{
	int matchCount = 0;

	FileIterator* it = getIterator();
	File* child;

	while ((child = it->next())  !=  NULL) {
		bool matches = finder.matches(*child);
		if (matches) {
			results.push_back(child);
			matchCount++;
		}

		if (finder.isInterrupted()) {
			if (!matches) {
				delete child;
			}
			return matchCount;
		}

		if (recursive  &&  (child->isDirectory()  ||  (archiveEntries  &&  child->isArchiveFile()))) {
			matchCount += child->findChildren(finder, results, true, archiveEntries);
		}

		if (!matches) {
			delete child;
		}
	}

	delete it;
	return matchCount;
}
Пример #4
0
void  commands_ns::Format(FileSystem *fs, int argc, char *argv[], std::ostream& out) // модуль не доработан жду модуля Delete()
{
	if (argc != 3)
	{
		out << "Неверное количество параметров"<< std::endl;
		return;
	}
	else
	{
		//size_t szt = atoi(argv[2]);
		
		if (fs->names_types(argv[0]) || fs->names_types(argv[1]) || fs->fssize(argv[2]))
		{
			out << "Некорректные данные" << std::endl;
			return;
		}
		else
		{
			FileIterator *fIter = fs->GetIterator();
			fs->SetTomName(argv[0]);
			fs->SetOwner(argv[1]);
			fs->SetMaxSize(atoi(argv[2]));
			while (fIter->HasNext())
			{
				fIter->Next();
				fIter->Delete();
			}
			fIter->Close();
			out << "Форматирование ФС успешно" << std::endl;
		}
	}
}
Пример #5
0
int File::indexOf(const File& other) const
{
	if (!isDirectory()  &&  !isArchiveFile()) {
		char* errmsg = new char[path->toString().length() + 128];
		sprintf(errmsg, "Called indexOf(const File&) with an invalid file type: '%s'",
				path->toString().get());
		FileException ex(errmsg, __FILE__, __LINE__);
		delete[] errmsg;
		throw ex;
	}

	FileIterator* it = getIterator();

	int i = 0;
	File* child;

	while ((child = it->next())  !=  NULL) {
		if (child->getPath()->toString() == other.getPath()->toString()) {
			delete child;
			delete it;
			return i;
		}

		i++;
		delete child;
	}

	delete it;

	return -1;
}
Пример #6
0
File* File::findChild(FileFinder& finder, bool recursive, bool archiveEntries) const
{
	FileIterator* it = getIterator();
	File* child;

	while ((child = it->next())  !=  NULL) {
		if (finder.matches(*child)) {
			delete it;
			return child;
		}

		if (finder.isInterrupted()) {
			delete child;
			return NULL;
		}

		if (recursive  &&  (child->isDirectory()  ||  (archiveEntries  &&  child->isArchiveFile()))) {
			File* match = child->findChild(finder, true, archiveEntries);

			if (match) {
				delete child;
				delete it;
				return match;
			}
		}

		delete child;
	}

	delete it;
	return NULL;
}
Пример #7
0
//---------------------------------------------------------------------------
uint FileIterator::getFilesList (const char* pszDirectory, bool bRecursive, StringAVec& vecOutFiles, flags8 fQueryFilter/*=QUERY_DIRS_AND_FILES*/)
{
  FileIterator fit;
  FileInfo     fi;
  uint         uiCounter = 0;

  fi.fQueryFlags = QUERY_NAMEONLY | (fQueryFilter & QUERYMASK_FILTERS);
  if (bRecursive)
    fi.fQueryFlags |= QUERY_TYPE | QUERY_DIRS;

  if (fit.openDir(pszDirectory, fi))
  {
    do
    {
      if ((fi.eType == TYPE_DIRECTORY && (fQueryFilter & QUERY_DIRS)) ||
        (fi.eType == TYPE_FILE && (fQueryFilter & QUERY_FILES)))
      {
        vecOutFiles.push_back(fit.getDirectory() / fi.strName);
        ++uiCounter;
      }

      if (bRecursive && fi.eType == TYPE_DIRECTORY)
      {
        uiCounter += FileIterator::getFilesList(
          fit.getDirectory() / fi.strName,
          bRecursive,
          vecOutFiles,
          fQueryFilter);
      }
    }
    while (fit.getNext(fi));
  }

  return uiCounter;
}
Пример #8
0
int File::getChildCount(bool recursive, bool archiveEntries) const
{
	if (isRegularFile()) {
		FileContentType type = guessContentType();

		if (type != CONTENT_TYPE_DIR  &&  type != CONTENT_TYPE_IMG) {
			return 0;
		} else {
			if (!recursive  ||  archiveEntries) {
				//IMGArchive img(*this);
				//return img.getEntryCount();
				return getIMGArchive()->getEntryCount();
			} else {
				return 0;
			}
		}
	} else if (!isDirectory()) {
		return 0;
	}

	FileIterator* it = getIterator();

	int i = 0;
	File* child;

	while ((child = it->next())  !=  NULL) {
		if (recursive) {
			i += child->getChildCount(true, archiveEntries);
		}

		delete child;
		i++;
	}

	delete it;

	return i;
}
Пример #9
0
//---------------------------------------------------------------------------
uint FileIterator::getFilesInfo (const char* pszDirectory, bool bRecursive, std::vector<FileIterator::FileInfo>& vecOutFilesInfo, flags8 fQueryFlags/*=QUERY_DIRS_AND_FILES*/)
{
  FileIterator fit;
  FileInfo     fi;
  uint         uiCounter = 0;

  fi.fQueryFlags = fQueryFlags;
  if (bRecursive)
    fi.fQueryFlags |= QUERY_TYPE | QUERY_DIRS;

  if (fit.openDir(pszDirectory, fi))
  {
    do
    {
      fi.strName = fit.getDirectory() / fi.strName;

      if ((fi.eType == TYPE_DIRECTORY && (fQueryFlags & QUERY_DIRS)) ||
        (fi.eType == TYPE_FILE && (fQueryFlags & QUERY_FILES)))
      {
        vecOutFilesInfo.push_back(fi);
        ++uiCounter;
      }

      if (bRecursive && fi.eType == TYPE_DIRECTORY)
      {
        uiCounter += FileIterator::getFilesInfo(
          fi.strName,
          bRecursive,
          vecOutFilesInfo,
          fQueryFlags);
      }
    }
    while (fit.getNext(fi));
  }

  return uiCounter;
}
Пример #10
0
void commands_ns::AddToFile(FileSystem *fs, int argc, char *argv[], std::ostream& out)
{
	size_t size = 0;
	if (argc != 2)
	{
		out << "Неправильное количество параметров" << std::endl;
		return;
	}
	char *nt[2];
	nt[0] = strtok(argv[0], ".");
	nt[1] = strtok(NULL, "");
	char *s = strtok(NULL, ".,-!");
	if ((!nt[0]) || (!nt[1]) || (s))
	{
		out << "Введены некорректные данные" << std::endl;
		return;
	}

	if (fs->names_types(nt[0])||fs->names_types(nt[1]))
	{
		out << "Введены некорректные данные" << std::endl;
		return;
	}
	if (fs->GetFilesCount() <= 0)
	{
		out << "Файл не найден" << std::endl;
		return;
	}
	if ((!argv[1]) || (strlen(argv[1]) <= 0))
	{
		out << "Информация для добавления не введена" << std::endl;
		return;
	}
	int addSize = strlen(argv[1]);
	int fileIndx = -1;
	//формируем список блоков из дескрипторов по возрастанию смещения======
	std::list < MemList> List;
	std::list<MemList>::iterator iter;
	std::list<MemList>::iterator fileToAdd;
	FileIterator *fi = fs->GetIterator();
	FileDescriptor *fd;
	MemList ml;
	unsigned int indx = 0, max_indx;
	while (fi->HasNext())
	{
		fi->Next();
		fd = fi->GetFileDescriptor();
		if ((strcmpi(fd->GetName(), nt[0]) == 0) && (strcmpi(fd->GetType(), nt[1]) == 0))
		{
			fileIndx = indx;
		}
		ml.FDescrPtr = fd;
		ml.offset = fd->GetOffset();
		ml.sz = fd->GetSize();
		ml.index = indx;
		if (List.empty())
		{
			List.push_back(ml);
			if (indx == fileIndx) {fileToAdd = List.begin();}
		}
		else
		{
			for (iter = List.begin(); iter != List.end(); iter++)
			{
				if ((ml.offset < (*iter).offset) || ((ml.offset == (*iter).offset) && (ml.sz < (*iter).sz)))
				{
					List.insert(iter, ml);
					if (indx == fileIndx) { fileToAdd = std::prev(iter); }
					break;
				}
			}
			if (iter == List.end())
			{
				List.push_back(ml);
				if (indx == fileIndx) { fileToAdd = std::prev(List.end()); }
			}
		}
		++indx;
	}
	max_indx = indx - 1;
	if (fileIndx==-1)
	{
		out << "Файл с указанным именем не существует" << std::endl;
		return;
	}
	//вставляем пустой блок в начало, если нужно
	size_t FD_END = 0;
	if ((*(List.begin())).offset > FD_END)
	{
		ml.offset = FD_END;
		ml.sz = (*(List.begin())).offset - FD_END;
		ml.FDescrPtr = NULL;
		List.insert(List.begin(), ml);
	}
	//вставляем пустые блоки в список
	for (iter = List.begin(); iter != List.end(); iter++)
	{
		if (std::next(iter) != List.end())
		{
			if ((*(std::next(iter))).offset != ((*iter).offset + (*iter).sz))
			{
				ml.offset = (*iter).offset + (*iter).sz;
				ml.sz = (*(std::next(iter))).offset - ml.offset;
				ml.FDescrPtr = NULL;
				List.insert(std::next(iter), ml);
				++iter;
			}
		}
	}
	//проверяем размер
	size_t MaxSz = fs->GetMaxSize();
	if (((*(std::prev(List.end()))).offset + (*(std::prev(List.end()))).sz+addSize) > MaxSz)
	{
		out << "Недостаточно места для добавления введенной информации" << std::endl;
		return;
	}
	//меняем размер файла, в который добавляется информация
	(*fileToAdd).sz += addSize;
	(*fileToAdd).FDescrPtr->SetSize((*fileToAdd).sz);
	if (std::next(fileToAdd) == List.end())//если файл последний в памяти - просто добавляем в размер
	{
		fi = fs->GetIterator();
		int i = 0;
		while (fi->HasNext())
		{
			fi->Next();
			if (i == (*fileToAdd).index)
			{
				fi->SetFileDescriptor((*fileToAdd).FDescrPtr);
				break;
			}
		}
		out << "Информация добавлена" << std::endl;
		return;
	}
	//если не последний - ищем подходящую "дырку"
	bool isMoved = false;
	for (iter = List.begin(); iter != List.end(); iter++)
	{
		if (((*iter).FDescrPtr == NULL) && ((*iter).sz >= (*fileToAdd).sz))
		{
			MemList ml = (*fileToAdd);
			List.erase(fileToAdd);
			ml.offset = (*iter).offset;
			(*iter).sz -= ml.sz;
			(*iter).offset += ml.sz;
			std::list<MemList>::iterator movedFile = List.insert(iter, ml);
			(*movedFile).FDescrPtr->SetOffset((*movedFile).offset);
			if ((*iter).sz <= 0)
			{
				List.erase(iter);
			}
			fileToAdd = movedFile;
			isMoved = true;
			break;
		}
	}
	//если нет подходящей дырки - сдвигаем все следующие блоки
	if (!isMoved)
	{
		for (iter = std::next(fileToAdd); iter != List.end(); iter++)
		{
			(*iter).offset += addSize;
		}
	}
	//меняем дескрипторы и записываем их в файл в нужном порядке
	fi = fs->GetIterator();
	for (indx = 0; indx <= max_indx; indx++)
	{
		for (iter = List.begin(); ((iter != List.end()) && ((*iter).index != indx)); iter++) {}
		fi->Next();
		(*iter).FDescrPtr->SetOffset((*iter).offset);
		fi->SetFileDescriptor((*iter).FDescrPtr);
	}
	fi->Close();
	out << "Информация добавлена" << std::endl;
	return;
}
Пример #11
0
void commands_ns::ChType(FileSystem *fs, int argc, char *argv[], std::ostream& out)
{
	FileIterator* fi = fs->GetIterator();
	int i = 0, count = strlen(argv[0]), flag = 1;
	char *arg_name = new char[count];
	if (argc != 2)
	{
		out << "Неправильное количество параметров" << std::endl;
		delete[] arg_name;
		return;
	}

	while (argv[0][i] != '.')
	{
		arg_name[i] = argv[0][i];
		++i;
		if (i > count - 2)
		{
			out << "Введены некорректные данные" << std::endl;
			delete[] arg_name;
			return;
		}
	}

	if (i == 0)
	{
		out << "Введены некорректные данные" << std::endl;
		delete[] arg_name;
		return;
	}

	arg_name[i] = '\0'; count -= i; ++i;
	char *arg_type = new char[count];
	count = 0;
	while (argv[0][i])
	{
		arg_type[count] = argv[0][i];
		++i;
		++count;
	}

	arg_type[count] = '\0';
	count = 0;

	if (fs->names_types(arg_name) || fs->names_types(arg_type)||fs->names_types(argv[1]))
	{
		out << "Введены некорректные данные" << std::endl;
		delete[] arg_name;
		delete[] arg_type;
		return;
	}

	if (fs->GetFilesCount() != 0)
	{
		while (fi->HasNext())
		{
			fi->Next();
			FileDescriptor* fd = fi->GetFileDescriptor();
			if (strcmpi(fd->GetName(), arg_name) == 0 && strcmpi(fd->GetType(), arg_type) == 0)
			{
				if (strcmp(arg_type,argv[1])==0){
					out << "Изменение имени прошло успешно" << std::endl;
					delete[] arg_name;
 					delete[] arg_type;
					return;
				}
				FileIterator* fi2 = fs->GetIterator();
				while (fi2->HasNext())
				{
					fi2->Next();
					FileDescriptor* fd2 = fi2->GetFileDescriptor();
					if (strcmpi(fd2->GetName(), arg_name) == 0 && strcmpi(fd2->GetType(), argv[1]) == 0)
						{
							out << "Файл с таким именем и типом уже существует" << std::endl;
							delete[] arg_name;
							delete[] arg_type;
							return;
						}
				}
				flag = 0;
				fd->SetType(argv[1]);
				fi->SetFileDescriptor(fd);
				out << "Изменение имени прошло успешно" << std::endl;
				delete[] arg_name;
 				delete[] arg_type;
				return;
			}
			++count;
		}
	}
	if (flag == 1)
	{
		out << "Файла в системе не обнаружено" << std::endl;
	}

	delete[] arg_name;
 	delete[] arg_type;
}
Пример #12
0
void commands_ns::DelFile(FileSystem *fs, int argc, char *argv[], std::ostream& out)

{
	if (argc != 1)
	{
		out << "Неправильное количество параметров" << std::endl;
		return;
	}
	if (strlen(argv[0]) > 41)
	{
		out << "Введены некорректные данные" << std::endl;
		return;
	}
	char *nt[2];
	nt[0] = strtok(argv[0], ".");
	nt[1] = strtok(NULL, "");
	char *s = strtok(NULL, ".,-!");
	if ( (!nt[0]) || (!nt[1]) || (s) )
	{
		out << "Введены некорректные данные" << std::endl;
		return;
	}
	if (fs->names_types(nt[0])||fs->names_types(nt[1]))
	{
		out << "Введены некорректные данные" << std::endl;
		return;
	}
	FileIterator* fi = fs->GetIterator();
	FileIterator* prevfi = fs->GetIterator();
	int j = 0;
	int next_index;
	int n = fs->GetFilesCount();
	if (fs->GetFilesCount() != 0)
	{
		while (fi->HasNext())
		{
			fi->Next();
			FileDescriptor* fd = fi->GetFileDescriptor();
			next_index = fi->GetNextIndex();

			if (strcmpi(fd->GetName(), nt[0]) == 0
				&& strcmpi(fd->GetType(), nt[1]) == 0)
			{
				if (j == 0)
				{
					fs->set_first_file(next_index);
				}
				else
				{
					prevfi->set_next(next_index);
				}
				fi->Delete();
				out << "Файл удален." << std::endl;
				return;
			}
			prevfi->Next();
			j++;
		}
		out << "Файл с указанным именем не существует" << std::endl;
	}
	else
		out << "Файлов в системе не обнаружено." << std::endl;

}
Пример #13
0
void commands_ns::Cmprs(FileSystem *fs, int argc, char *argv[], std::ostream& out)
{
	if (argc > 0) { out << "This command must be used without argumnents" << std::endl; return; }
	if (fs->GetFilesCount() <= 0) { out << "no files" << std::endl; return; }//проверяем наличие файлов
	//формируем список блоков из дескрипторов по возрастанию смещения======
	std::list < MemList> List;
	std::list<MemList>::iterator iter;
	FileIterator *fi = fs->GetIterator();
	FileDescriptor *fd;
	MemList ml;
	unsigned int indx = 0, max_indx;
	while (fi->HasNext())
	{
		fi->Next();
		fd = fi->GetFileDescriptor();
		ml.FDescrPtr = fd;
		ml.offset = fd->GetOffset();
		ml.sz = fd->GetSize();
		ml.index = indx;
		if (List.empty())
		{
			List.push_front(ml);
		}
		else
		{
			for (iter = List.begin(); iter != List.end(); iter++)
			{
				if ( (ml.offset < (*iter).offset) || ((ml.offset == (*iter).offset) && (ml.sz < (*iter).sz)) )
				{
					List.insert(iter, ml);
					break;
				}
			}
			if (iter == List.end())
			{
				List.push_back(ml);
			}
		}
		++indx;
	}
	max_indx = indx - 1;
	//вставляем пустой блок в начало, если нужно
	size_t FD_END = 0;//START_OF_FILE_SPACE;
	if ((*(List.begin())).offset > FD_END)
	{
		ml.offset = FD_END;
		ml.sz = (*(List.begin())).offset - FD_END;
		ml.FDescrPtr = NULL;
		//List.insert(List.begin(), ml);
		List.push_front(ml);
	}
	//вставляем пустые блоки в список
	for (iter = List.begin(); iter != List.end(); iter++)
	{
		if (std::next(iter) != List.end())
		{
			if ((*(std::next(iter))).offset != ((*iter).offset + (*iter).sz))
			{
				ml.offset = (*iter).offset + (*iter).sz;
				ml.sz = (*(std::next(iter))).offset - ml.offset;
				ml.FDescrPtr = NULL;
				List.insert(std::next(iter), ml);
				++iter;
			}
		}
	}
	//=========================================================*/
	out << "The whole data size before compressing: " << ((*(std::prev(List.end()))).offset + (*(std::prev(List.end()))).sz - (*(List.begin())).offset) << std::endl;
	//сжатие===================================================
	for (iter = List.begin(); iter != List.end(); iter++)
	{
		if (!((*iter).FDescrPtr))//если текущий блок пустой
		{
			if (std::next(iter) != List.end())//если не последний
			{
				//ищем наибольший влезающий в текущий пустой блок с конца
				std::list<MemList>::iterator MaxAppr = List.end();
				for (std::list<MemList>::iterator insIter = std::prev(List.end()); insIter != iter; insIter--)
				{
					if ((*insIter).FDescrPtr)
					{
						if ( ( (MaxAppr == List.end()) || ((*insIter).sz > (*MaxAppr).sz) ) && ((*insIter).sz <= (*iter).sz) && ((*insIter).sz > 0) )
						{
							MaxAppr = insIter;
						}
					}
				}
				if (MaxAppr != List.end())//если нашёлся
				{
					MemList mlCopy = (*MaxAppr);//копируем
					//делаем перемещаемый блок пустым
					(*MaxAppr).FDescrPtr = NULL;
					if ( (std::next(MaxAppr) != List.end()) && ((*(std::next(MaxAppr))).FDescrPtr == NULL) )//если следующий пустой - объединяем
					{
						size_t rmv_size = (*(std::next(MaxAppr))).sz;
						List.erase(std::next(MaxAppr));
						(*MaxAppr).sz += rmv_size;
					}
					if ((*(std::prev(MaxAppr))).FDescrPtr == NULL)//аналогично с предыдущим
					{
						size_t rmv_size = (*MaxAppr).sz;
						std::list<MemList>::iterator li = std::prev(MaxAppr);
						(*li).sz += rmv_size;
						List.erase(MaxAppr);
					}
					//вставляем копию перед текущим пустым блоком
					mlCopy.offset = (*iter).offset;
					List.insert(iter, mlCopy);
					//корректируем смещение и размер пустого блока после вставки
					(*iter).sz -= mlCopy.sz;
					(*iter).offset += mlCopy.sz;
					//если перемещаемый блок полностью заполнил пустой блок - удаляем текущий пустой блок
					if ((*iter).sz == 0)
					{
						std::list<MemList>::iterator li = std::prev(iter);
						List.erase(iter);
						iter = li;//ставим указатель на предыдущий
					}
					else//если пустое место осталось
					{
						if ( (std::next(iter) != List.end()) && ((*(std::next(iter))).FDescrPtr == NULL) )//если следущий пуст - объединяем
						{
							size_t rmv_size = (*(std::next(iter))).sz;
							List.erase(std::next(iter));
							(*iter).sz += rmv_size;
						}
						--iter;//ставим указатель на предыдущий (он существует, так как только что вставили)
					}
				}
				else//если не нашёлся блок для вставки
				{
					//удаляем текущий пустой блок
					size_t rmv_size = (*iter).sz;
					std::list<MemList>::iterator insIter = List.erase(iter);
					//уменьшаем смещение всех последующих до пустого блока
					for (; ((*insIter).FDescrPtr && (insIter != List.end())); insIter++)
					{
						(*insIter).offset -= rmv_size;
					}
					//если встретился пустой блок
					if (insIter != List.end())
					{
						(*insIter).offset -= rmv_size;//уменьшаем смещение
						(*insIter).sz += rmv_size;//увеличиваем размер
						iter = insIter;//ставим указатель на предыдущий блок
						--iter;
					}
					else//если нет больше пустых блоков - завершаем цикл
					{
						break;
					}
				}
			}
			else//если последний
			{
				List.erase(iter);//удаляем
				break;//выходим из цикла
			}
		}
	}
	//записываем изменения в файл================
	for (iter = List.begin(); iter != List.end(); iter++) { (*iter).FDescrPtr->SetOffset((*iter).offset); }//меняем смещение в дескрипторах
	fi = fs->GetIterator();
	for (indx = 0; indx <= max_indx; indx++)
	{
		for (iter = List.begin(); ( (iter != List.end()) && ((*iter).index != indx) ); iter++) {}
		fi->Next();
		fi->SetFileDescriptor((*iter).FDescrPtr);
	}
	fi->Close();
	//выводим результат
	out << "The whole data size after compressing: " << ( (*(std::prev(List.end()))).offset + (*(std::prev(List.end()))).sz - (*(List.begin())).offset) << std::endl;
}
Пример #14
0
File* File::getChild(int childIdx) const
{
	if (physicallyExists()) {
		if (isRegularFile()) {
			FileContentType type = guessContentType();

			if (type == CONTENT_TYPE_DIR  ||  type == CONTENT_TYPE_IMG) {
				try {
					boost::shared_ptr<IMGArchive> archive = getIMGArchive();

					if (childIdx >= archive->getEntryCount()) {
						return NULL;
					}

					IMGArchive::EntryIterator it = archive->getEntryBegin();
					for (int i = 0 ; it != archive->getEntryEnd()  &&  i < childIdx ; it++, i++);

					return new File(*this, (*it)->name);
				} catch (Exception& ex) {
					char* errMsg = new char[path->toString().length() + 64];
					sprintf(errMsg, "Exception thrown during child count of IMG archive %s.",
							path->toString().get());
					FileException fex(errMsg, __FILE__, __LINE__, &ex);
					delete[] errMsg;
					throw fex;
				}
			} else {
				char* errmsg = new char[path->toString().length() + 128];
				sprintf(errmsg, "Called getChild(int) with a regular non-archive file: '%s'",
						path->toString().get());
				FileException ex(errmsg, __FILE__, __LINE__);
				delete[] errmsg;
				throw ex;
			}
		} else if (isDirectory()) {
			FileIterator* it = getIterator();
			File* nextFile = NULL;

			for (int i = 0 ; i <= childIdx ; i++) {
				if (nextFile != NULL) {
					delete nextFile;
				}

				nextFile = it->next();

				if (nextFile == NULL) {
					break;
				}
			}

			delete it;

			return nextFile;
		} else {
			char* errmsg = new char[path->toString().length() + 128];
			sprintf(errmsg, "Called getChild(int) with file of invalid type: '%s'", path->toString().get());
			FileException ex(errmsg, __FILE__, __LINE__);
			delete[] errmsg;
			throw ex;
		}
	} else {
		char* errmsg = new char[path->toString().length() + 128];
		sprintf(errmsg, "Called getChild(int) with a non-existant file: '%s'", path->toString().get());
		FileException ex(errmsg, __FILE__, __LINE__);
		delete[] errmsg;
		throw ex;
	}
}
Пример #15
0
    int CompactBlock::real_compact(LogicBlock* src, LogicBlock* dest)
    {
      assert(NULL != src && NULL != dest);

      BlockInfo dest_blk;
      BlockInfo* src_blk = src->get_block_info();
      dest_blk.block_id_ = src_blk->block_id_;
      dest_blk.seq_no_ = src_blk->seq_no_;
      dest_blk.version_ = src_blk->version_;
      dest_blk.file_count_ = 0;
      dest_blk.size_ = 0;
      dest_blk.del_file_count_ = 0;
      dest_blk.del_size_ = 0;

      dest->set_last_update(time(NULL));
      TBSYS_LOG(DEBUG, "compact block set last update. blockid: %u\n", dest->get_logic_block_id());

      char* dest_buf = new char[MAX_COMPACT_READ_SIZE];
      int32_t write_offset = 0, data_len = 0;
      int32_t w_file_offset = 0;
      RawMetaVec dest_metas;
      FileIterator* fit = new FileIterator(src);

      int ret = TFS_SUCCESS;
      while (fit->has_next())
      {
        ret = fit->next();
        if (TFS_SUCCESS != ret)
        {
          tbsys::gDeleteA(dest_buf);
          tbsys::gDelete(fit);
          return ret;
        }

        const FileInfo* pfinfo = fit->current_file_info();
        if (pfinfo->flag_ & (FI_DELETED | FI_INVALID))
        {
          continue;
        }

        FileInfo dfinfo = *pfinfo;
        dfinfo.offset_ = w_file_offset;
        // the size returned by FileIterator.current_file_info->size is
        // the size of file content!!!
        dfinfo.size_ = pfinfo->size_ + sizeof(FileInfo);
        dfinfo.usize_ = pfinfo->size_ + sizeof(FileInfo);
        w_file_offset += dfinfo.size_;

        dest_blk.file_count_++;
        dest_blk.size_ += dfinfo.size_;

        RawMeta tmp_meta;
        tmp_meta.set_file_id(dfinfo.id_);
        tmp_meta.set_size(dfinfo.size_);
        tmp_meta.set_offset(dfinfo.offset_);
        dest_metas.push_back(tmp_meta);

        // need flush write buffer
        if ((0 != data_len) && (fit->is_big_file() || data_len + dfinfo.size_ > MAX_COMPACT_READ_SIZE))
        {
          TBSYS_LOG(DEBUG, "write one, blockid: %u, write offset: %d\n", dest->get_logic_block_id(),
              write_offset);
          ret = dest->write_raw_data(dest_buf, data_len, write_offset);
          if (TFS_SUCCESS != ret)
          {
            TBSYS_LOG(ERROR, "write raw data fail, blockid: %u, offset %d, readinglen: %d, ret :%d",
                dest->get_logic_block_id(), write_offset, data_len, ret);
            tbsys::gDeleteA(dest_buf);
            tbsys::gDelete(fit);
            return ret;
          }
          write_offset += data_len;
          data_len = 0;
        }

        if (fit->is_big_file())
        {
          ret = write_big_file(src, dest, *pfinfo, dfinfo, write_offset);
          write_offset += dfinfo.size_;
        }
        else
        {
          memcpy(dest_buf + data_len, &dfinfo, sizeof(FileInfo));
          int left_len = MAX_COMPACT_READ_SIZE - data_len;
          ret = fit->read_buffer(dest_buf + data_len + sizeof(FileInfo), left_len);
          data_len += dfinfo.size_;
        }
        if (TFS_SUCCESS != ret)
        {
          tbsys::gDeleteA(dest_buf);
          tbsys::gDelete(fit);
          return ret;
        }

      } // end of iterate

      if (0 != data_len) // flush the last buffer
      {
        TBSYS_LOG(DEBUG, "write one, blockid: %u, write offset: %d\n", dest->get_logic_block_id(), write_offset);
        ret = dest->write_raw_data(dest_buf, data_len, write_offset);
        if (TFS_SUCCESS != ret)
        {
          TBSYS_LOG(ERROR, "write raw data fail, blockid: %u, offset %d, readinglen: %d, ret :%d",
              dest->get_logic_block_id(), write_offset, data_len, ret);
          tbsys::gDeleteA(dest_buf);
          tbsys::gDelete(fit);
          return ret;
        }
      }

      tbsys::gDeleteA(dest_buf);
      tbsys::gDelete(fit);
      TBSYS_LOG(DEBUG, "compact write complete. blockid: %u\n", dest->get_logic_block_id());

      ret = dest->batch_write_meta(&dest_blk, &dest_metas);
      if (TFS_SUCCESS != ret)
      {
        TBSYS_LOG(ERROR, "compact write segment meta failed. blockid: %u, meta size %zd\n", dest->get_logic_block_id(),
            dest_metas.size());
        return ret;
      }

      TBSYS_LOG(DEBUG, "compact set dirty flag. blockid: %u\n", dest->get_logic_block_id());
      ret = dest->set_block_dirty_type(C_DATA_CLEAN);
      if (TFS_SUCCESS != ret)
      {
        TBSYS_LOG(ERROR, "compact blockid: %u set dirty flag fail. ret: %d\n", dest->get_logic_block_id(), ret);
        return ret;
      }

      return TFS_SUCCESS;
    }