⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 basicexcel.cpp

📁 Excel for add/delete item or sheet compile in VS2008/VC9 no error and no warnning
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/********************************** End of Class PropertyTree ************************************/

/********************************** Start of Class CompoundFile ******************************/
// PURPOSE: Manage a compound file.
CompoundFile::CompoundFile() :
	block_(512), properties_(0), propertyTrees_(0),
	blocksIndices_(0), sblocksIndices_(0) {};

CompoundFile::~CompoundFile() {this->Close();}

/************************* Compound File Functions ***************************/
bool CompoundFile::Create(const wchar_t* filename)
// PURPOSE: Create a new compound file and open it.
// PURPOSE: If file is present, truncate it and then open it.
// PROMISE: Return true if file is successfully created and opened, false if otherwise.
{
	Close();
	file_.Create(filename);

	// Write compound file header
	header_ = Header();
	SaveHeader();

	// Save BAT
	blocksIndices_.clear();
	blocksIndices_.resize(128, -1);
	blocksIndices_[0] = -3;
	blocksIndices_[1] = -2;
	SaveBAT();

	// Save properties
	Property* root = new Property;
	wcscpy(root->name_, L"Root Entry");
	root->propertyType_ = 5;
	properties_.push_back(root);
	SaveProperties();

	// Set property tree
	propertyTrees_ = new PropertyTree;	
	propertyTrees_->parent_ = 0;
	propertyTrees_->self_ = properties_[0];
	propertyTrees_->index_ = 0;
	currentDirectory_ = propertyTrees_;

	return true;
}

bool CompoundFile::Open(const wchar_t* filename, ios_base::openmode mode)
// PURPOSE: Open an existing compound file.
// PROMISE: Return true if file is successfully opened, false if otherwise.
{
	Close();
	if (!file_.Open(filename, mode)) return false;
	
	// Load header
	if (!LoadHeader()) return false;

	// Load BAT information
	LoadBAT();	

	// Load properties
	propertyTrees_ = new PropertyTree;	
	LoadProperties();
	currentDirectory_ = propertyTrees_;

	return true;
}

bool CompoundFile::Close()
// PURPOSE: Close the opened compound file.
// PURPOSE: Reset BAT indices, SBAT indices, properties and properties tree information.
// PROMISE: Return true if file is successfully closed, false if otherwise.
{
	blocksIndices_.clear();
	sblocksIndices_.clear();

	int maxProperties = properties_.size();
	for (int i=0; i<maxProperties; ++i)
	{
		if (properties_[i]) delete properties_[i];
	}
	properties_.clear();

	if (propertyTrees_) 
	{
		delete propertyTrees_;
		propertyTrees_ = 0;
	}

	previousDirectories_.clear();
	currentDirectory_ = 0;

	return file_.Close();
}

bool CompoundFile::IsOpen()
// PURPOSE: Check if the compound file is still opened.
// PROMISE: Return true if file is still opened, false if otherwise.
{
	return file_.IsOpen();
}

/************************* Directory Functions ***************************/
int CompoundFile::ChangeDirectory(const wchar_t* path)
// PURPOSE: Change to a different directory in the compound file.
// PROMISE: Current directory will not be changed if directory is not present.
{
	previousDirectories_.push_back(currentDirectory_);

	// Handle special cases
	if (wcscmp(path, L".") == 0) 	
	{
		// Current directory
		previousDirectories_.pop_back();
		return SUCCESS;
	}
	if (wcscmp(path, L"..") == 0)
	{
		// Go up 1 directory
		if (currentDirectory_->parent_ != 0)
		{
			currentDirectory_ = currentDirectory_->parent_;
		}
		previousDirectories_.pop_back();
		return SUCCESS;
	}
	if (wcscmp(path, L"\\") == 0)
	{
		// Go to root directory
		currentDirectory_ = propertyTrees_;
		previousDirectories_.pop_back();
		return SUCCESS;
	}

	// Handle normal cases
	int ipos = 0;
	int npos = 0;
	int pathLength = wcslen(path);
	if (pathLength > 0 && path[0] == L'\\')
	{
		// Start from root directory
		currentDirectory_ = propertyTrees_;
		++ipos;
		++npos;
	}
	do
	{
		for (; npos<pathLength; ++npos)
		{
			if (path[npos] == L'\\') break; 
		}

		wchar_t* directory = new wchar_t[npos-ipos+1];
		//copy (path+ipos, path+npos, directory);
		wmemcpy(directory, path+ipos, npos-ipos);
		directory[npos-ipos] = 0;
		currentDirectory_ = FindProperty(currentDirectory_, directory);
		delete[] directory;
		ipos = npos + 1;
		npos = ipos;
		if (currentDirectory_ == 0)
		{
			// Directory not found
			currentDirectory_ = previousDirectories_.back();
			previousDirectories_.pop_back();
			return DIRECTORY_NOT_FOUND;
		}
	} while (npos < pathLength);
	previousDirectories_.pop_back();
	return SUCCESS;
}

int CompoundFile::MakeDirectory(const wchar_t* path)
// PURPOSE: Create a new directory in the compound file.
// PROMISE: Directory will not be created if it is already present or
// PROMISE: a file with the same name is present.
{
	previousDirectories_.push_back(currentDirectory_);
	Property* property = new Property;
	property->propertyType_ = 1;
	int ret = MakeProperty(path, property);
	currentDirectory_ = previousDirectories_.back();
	previousDirectories_.pop_back();
	SaveHeader();
	SaveBAT();
	SaveProperties();
	return ret;
}

int CompoundFile::PresentWorkingDirectory(wchar_t* path)
// PURPOSE: Get the full path of the current directory in the compound file.
// REQUIRE: path must be large enough to receive the full path information.
{
	previousDirectories_.push_back(currentDirectory_);
	vector<wchar_t> fullpath;
	do
	{
		int directoryLength = wcslen(currentDirectory_->self_->name_);
		vector<wchar_t> directory(directoryLength+1);
		directory[0] = L'\\';
		copy (currentDirectory_->self_->name_,
			  currentDirectory_->self_->name_+directoryLength,
			  directory.begin()+1);
		fullpath.insert(fullpath.begin(), directory.begin(), directory.end());		
	} while (currentDirectory_ = currentDirectory_->parent_);

	fullpath.erase(fullpath.begin(), fullpath.begin()+11);
	if (fullpath.empty()) 
		fullpath.push_back(L'\\');
	//copy (fullpath.begin(), fullpath.end(), path);
	if( fullpath.size() > 0 )
		wmemcpy( path, &fullpath[0], fullpath.size());
	path[fullpath.size()] = 0;
	currentDirectory_ = previousDirectories_.back();
	previousDirectories_.pop_back();
	return SUCCESS;
}

int CompoundFile::PresentWorkingDirectory(vector<wchar_t>& path)
// PURPOSE: Get the full path of the current directory in the compound file.
{
	previousDirectories_.push_back(currentDirectory_);
	path.clear();
	do
	{
		int directoryLength = wcslen(currentDirectory_->self_->name_);
		vector<wchar_t> directory(directoryLength+1);
		directory[0] = L'\\';
		copy (currentDirectory_->self_->name_,
			  currentDirectory_->self_->name_+directoryLength,
			  directory.begin()+1);
		path.insert(path.begin(), directory.begin(), directory.end());		
	} while (currentDirectory_ = currentDirectory_->parent_);

	path.erase(path.begin(), path.begin()+11);
	if (path.empty()) path.push_back(L'\\');
	currentDirectory_ = previousDirectories_.back();
	previousDirectories_.pop_back();
	return SUCCESS;
}

int CompoundFile::RemoveDirectory(const wchar_t* path)
// PURPOSE: Remove a directory in the compound file.
// PROMISE: Directory will not be removed if it has subdirectories or files under it.
{
	PropertyTree* directory = FindProperty(path);
	if (directory == 0) return DIRECTORY_NOT_FOUND;
	if (directory->self_->childProp_ != -1) return DIRECTORY_NOT_EMPTY;
	DeletePropertyTree(directory);
	SaveHeader();
	SaveBAT();
	SaveProperties();
	return SUCCESS;
}

int CompoundFile::DelTree(const wchar_t* path)
// PURPOSE: Remove everything in the path in the compound file, including
// PURPOSE: any files and subdirectories.
{
	previousDirectories_.push_back(currentDirectory_);
	PropertyTree* directory = FindProperty(path);
	if (directory == 0) return DIRECTORY_NOT_FOUND;
	if (directory->self_->childProp_ != -1)
	{
		int maxChildren = directory->children_.size();
		wchar_t* curpath = new wchar_t[65535];
		for (int i=0; i<maxChildren; ++i)
		{
			currentDirectory_ = directory->children_[i];
			PresentWorkingDirectory(curpath);
			if (directory->children_[i]->self_->propertyType_ == 1)
			{	
				// Directory
				DelTree(curpath);
			}
			else if (directory->children_[i]->self_->propertyType_ == 2)
			{
				// File
				RemoveFile(curpath);
			}
		}
		directory->self_->childProp_ = -1;
		delete[] curpath;
	}

	if (directory->self_->propertyType_ == 1)
	{	
		// Directory
		RemoveDirectory(path);
	}
	else if (directory->self_->propertyType_ == 2)
	{
		// File
		RemoveFile(path);
	}

	currentDirectory_ = previousDirectories_.back();
	previousDirectories_.pop_back();
	return SUCCESS;
}

int CompoundFile::DirectoryList(vector<vector<wchar_t> >& list, const wchar_t* path)
{
	previousDirectories_.push_back(currentDirectory_);
	if (path != 0)
	{
		int ret = ChangeDirectory(path);
		if (ret != SUCCESS) return ret;
	}
	list.clear();
	int maxChildren = currentDirectory_->children_.size();
	vector<wchar_t> name(32);
	for (int i=0; i<maxChildren; ++i)
	{
		wcscpy(&*(name.begin()), currentDirectory_->children_[i]->self_->name_);
		list.push_back(name);
	}
	currentDirectory_ = previousDirectories_.back();
	previousDirectories_.pop_back();
	return SUCCESS;
}


/************************* File Functions ***************************/
int CompoundFile::MakeFile(const wchar_t* path)
// PURPOSE: Create a new file in the compound file.
// PROMISE: File will not be created if it is already present or
// PROMISE: a directory with the same name is present.
{
	previousDirectories_.push_back(currentDirectory_);
	Property* property = new Property;
	property->propertyType_ = 2;
	int ret = MakeProperty(path, property);
	currentDirectory_ = previousDirectories_.back();
	previousDirectories_.pop_back();
	SaveHeader();
	SaveBAT();
	SaveProperties();
	return ret;
}

int CompoundFile::RemoveFile(const wchar_t* path)
// PURPOSE: Remove a file in the compound file.
{
	int ret = WriteFile(path, 0, 0);
	if (ret == SUCCESS) 
	{
		DeletePropertyTree(FindProperty(path));
		SaveHeader();
		SaveBAT();
		SaveProperties();
		return SUCCESS;
	}
	else return ret;
}

int CompoundFile::FileSize(const wchar_t* path, int& size)
// PURPOSE: Get the size of a file in the compound file.
// PROMISE: Return the data size stored in the Root Entry if path = "\".
// PROMISE: size will not be set if file is not present in the compound file.
{
	// Special case of reading root entry
	if (wcscmp(path, L"\\") == 0)
	{
		size = propertyTrees_->self_->size_;
		return SUCCESS;
	}
	
	// Check to see if file is present in the specified directory.
	PropertyTree* property = FindProperty(path);
	if (property == 0) return FILE_NOT_FOUND;
	else
	{
		size = property->self_->size_;
		return SUCCESS;
	}
}

int CompoundFile::ReadFile(const wchar_t* path, char* data)
// PURPOSE: Read a file's data in the compound file.
// REQUIRE: data must be large enough to receive the file's data.
// REQUIRE: The required data size can be obtained by using FileSize().
// PROMISE: Returns the small blocks of data stored by the Root Entry if path = "\".
// PROMISE: data will not be set if file is not present in the compound file.
{
	// Special case of reading root entry
	char* buffer;
	if (wcscmp(path, L"\\") == 0)
	{
		buffer = new char[DataSize(propertyTrees_->self_->startBlock_, true)];
		ReadData(propertyTrees_->self_->startBlock_, buffer, true);
		//copy (buffer, buffer+propertyTrees_->self_->size_, data);
		memcpy(data, buffer, propertyTrees_->self_->size_);
		delete[] buffer;
		return SUCCESS;
	}

	// Check to see if file is present in the specified directory.
	PropertyTree* property = FindProperty(path);
	if (property == 0) return FILE_NOT_FOUND;

	if (property->self_->size_ >= 4096)
	{
		// Data stored in normal big blocks
		buffer = new char[DataSize(property->self_->startBlock_, true)];
		ReadData(property->self_->startBlock_, buffer, true);
	}
	else
	{
		// Data stored in small blocks
		buffer = new char[DataSize(property->self_->startBlock_, false)];
		ReadData(property->self_->startBlock_, buffer, false);
	}
	// Truncated the retrieved data to the actual file size.
	//copy (buffer, buffer+property->self_->size_, data);
	memcpy(data, buffer, property->self_->size_);
	delete[] buffer;
	return SUCCESS;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -