Beispiel #1
0
uint64 CFileDataIO::Seek(sint64 offset, wxSeekMode from) const
{
	sint64 newpos = 0;
	switch (from) {
		case wxFromStart:
			newpos = offset;
			break;
			
		case wxFromCurrent:
			newpos = GetPosition() + offset;
			break;
			
		case wxFromEnd:
			newpos = GetLength() + offset;
			break;
			
		default:
			MULE_VALIDATE_PARAMS(false, wxT("Invalid seek-mode specified."));
	}
	
	MULE_VALIDATE_PARAMS(newpos >= 0, wxT("Position after seeking would be less than zero!"));

	sint64 result = doSeek(newpos);
	MULE_VALIDATE_STATE(result >= 0, wxT("Seeking resulted in invalid offset."));
	MULE_VALIDATE_STATE(result == newpos, wxT("Target position and actual position disagree."));
	
	return result;
}
Beispiel #2
0
void CMuleListCtrl::SetSorting(unsigned column, unsigned order)
{
	MULE_VALIDATE_PARAMS(column < (unsigned)GetColumnCount(), wxT("Invalid column to sort by."));
	MULE_VALIDATE_PARAMS(!(order & ~SORTING_MASK), wxT("Sorting order contains invalid data."));
	
	if (!m_sort_orders.empty()) {
		SetColumnImage(m_sort_orders.front().first, -1);
	
		CSortingList::iterator it = m_sort_orders.begin();
		for (; it != m_sort_orders.end(); ++it) {
			if (it->first == column) {
				m_sort_orders.erase(it);
				break;
			}
		}
	}

	m_sort_orders.push_front(CColPair(column, order));	
	
	if (order & SORT_DES) {
		SetColumnImage(column, (order & SORT_ALT) ? 2 : 0);
	} else {
		SetColumnImage(column, (order & SORT_ALT) ? 3 : 1);
	}

	SortList();
}
Beispiel #3
0
void CFileDataIO::Write(const void* buffer, size_t count)
{
	MULE_VALIDATE_PARAMS(buffer, wxT("Attempting to read from NULL buffer."));

	if (doWrite(buffer, count) != (signed)count) {
		throw CIOFailureException(wxT("Write error, failed to write to file."));
	}
}
Beispiel #4
0
wxString CMuleListCtrl::GetTTSText(unsigned item) const
{
	MULE_VALIDATE_PARAMS(item < (unsigned)GetItemCount(), wxT("Invalid row."));
	MULE_VALIDATE_STATE((GetWindowStyle() & wxLC_OWNERDRAW) == 0,
		wxT("GetTTSText must be overwritten for owner-drawn lists."));

	return GetItemText(item);
}
Beispiel #5
0
void CFileDataIO::ReadTagPtrList(TagPtrList* taglist, bool bOptACP) const
{
	MULE_VALIDATE_PARAMS(taglist, wxT("NULL pointer argument in ReadTagPtrList"));

	uint32 count = ReadUInt8();
	for (uint32 i = 0; i < count; i++)
	{
		CTag* tag = ReadTag(bOptACP);
		taglist->push_back(tag);
	}
}
Beispiel #6
0
unsigned char* CFileDataIO::ReadBsob(uint8* puSize) const
{
	MULE_VALIDATE_PARAMS(puSize, wxT("NULL pointer argument in ReadBsob"));

	*puSize = ReadUInt8();
	
	CScopedArray<unsigned char> bsob(*puSize);
	Read(bsob.get(), *puSize);
	
	return bsob.release();
}
Beispiel #7
0
void CFileDataIO::WriteStringCore(const char *s, EUtf8Str eEncode, uint8 SizeLen)
{
	uint32 sLength = s ? strlen(s) : 0;
	uint32 real_length = 0;
	if (eEncode == utf8strOptBOM) {
		real_length = sLength + 3; // For BOM header.
	} else {
		real_length = sLength;
	}

	switch (SizeLen) {
		case 0:
			// Don't write size.
			break;
			
		case sizeof(uint16):
			// We must not allow too long strings to be written,
			// as this would allow for a buggy clients to "poison"
			// us, by sending ISO8859-1 strings that expand to a
			// greater than 16b length when converted as UTF-8.
			if (real_length > 0xFFFF) {
				wxFAIL_MSG(wxT("String is too long to be saved"));

				real_length = std::min<uint32>(real_length, 0xFFFF);
				if (eEncode == utf8strOptBOM) {
					sLength = real_length - 3;
				} else {
					sLength = real_length;
				}
			}
			
			WriteUInt16(real_length);
			break;
			
		case sizeof(uint32):
			WriteUInt32(real_length);
			break;
			
		default:
			MULE_VALIDATE_PARAMS(false, wxT("Invalid length for string-length field."));
	}		
		
	// The BOM header must be written even if the string is empty.
	if (eEncode == utf8strOptBOM) {
		Write(BOMHeader, 3);
	}

	// Only attempt to write non-NULL strings.
	if (sLength) {
		// No NULL terminator is written since we explicitly specify the length
		Write(s, sLength);
	}
}
Beispiel #8
0
sint64 CFile::doWrite(const void* buffer, size_t nCount)
{
	MULE_VALIDATE_PARAMS(buffer, wxT("CFile: Invalid buffer in write operation."));
	MULE_VALIDATE_STATE(IsOpened(), wxT("CFile: Cannot write to closed file."));

	sint64 result = ::write(m_fd, buffer, nCount);

	if (result != (sint64)nCount) {
		throw CIOFailureException(wxString(wxT("Error writing to file: ")) + wxSysErrorMsg());
	}

	return result;
}
Beispiel #9
0
sint64 CFile::doSeek(sint64 offset) const
{
	MULE_VALIDATE_STATE(IsOpened(), wxT("Cannot seek on closed file."));
	MULE_VALIDATE_PARAMS(offset >= 0, wxT("Invalid position, must be positive."));

	sint64 result = SEEK_FD(m_fd, offset, SEEK_SET);

	if (result == offset) {
		return result;
	} else if (result == wxInvalidOffset) {
		throw CSeekFailureException(wxString(wxT("Seeking failed: ")) + wxSysErrorMsg());
	} else {
		throw CSeekFailureException(wxT("Seeking returned incorrect position"));
	}
}
Beispiel #10
0
void CFileDataIO::Read(void *buffer, size_t count) const
{
	MULE_VALIDATE_PARAMS(buffer, wxT("Attempting to write to NULL buffer."));

	// Check that we read everything we wanted.
	if (doRead(buffer, count) == (signed)count) {
		return;
	}

	// To reduce potential system calls, we only do EOF checks when reads fail.
	if (Eof()) {
		throw CEOFException(wxT("Attempt to read past end of file."));
	} else {
		throw CIOFailureException(wxT("Read error, failed to read from file."));
	}
}
Beispiel #11
0
wxString CFileDataIO::ReadString(bool bOptUTF8, uint8 SizeLen, bool SafeRead) const
{
	uint32 readLen;
	switch (SizeLen) {
		case sizeof(uint16):	readLen = ReadUInt16();	break;
		case sizeof(uint32):	readLen = ReadUInt32();	break;
			
		default:
			MULE_VALIDATE_PARAMS(false, wxT("Invalid SizeLen value in ReadString"));
	}	

	if (SafeRead) {
		readLen = std::min<uint64>(readLen, GetLength() - GetPosition());
	}
	
	return ReadOnlyString(bOptUTF8, readLen);
}
Beispiel #12
0
sint64 CFile::doRead(void* buffer, size_t count) const
{
	MULE_VALIDATE_PARAMS(buffer, wxT("CFile: Invalid buffer in read operation."));
	MULE_VALIDATE_STATE(IsOpened(), wxT("CFile: Cannot read from closed file."));

	size_t totalRead = 0;
	while (totalRead < count) {
		int current = ::read(m_fd, (char*)buffer + totalRead, count - totalRead);

		if (current == -1) {
			// Read error, nothing we can do other than abort.
			throw CIOFailureException(wxString(wxT("Error reading from file: ")) + wxSysErrorMsg());
		} else if ((totalRead + current < count) && Eof()) {
			// We may fail to read the specified count in a couple
			// of situations: EOF and interrupts. The check for EOF
			// is needed to avoid inf. loops.
			break;
		}

		totalRead += current;
	}

	return totalRead;
}
Beispiel #13
0
bool CFile::Open(const CPath& fileName, OpenMode mode, int accessMode)
{
	MULE_VALIDATE_PARAMS(fileName.IsOk(), wxT("CFile: Cannot open, empty path."));

	if (IsOpened()) {
		Close();
	}

	m_safeWrite = false;
	m_filePath = fileName;

#ifdef __linux__
	int flags = O_BINARY | O_LARGEFILE;
#else
	int flags = O_BINARY;
#endif
	switch ( mode ) {
		case read:
			flags |= O_RDONLY;
			break;

		case write_append:
			if (fileName.FileExists())
			{
				flags |= O_WRONLY | O_APPEND;
				break;
			}
			//else: fall through as write_append is the same as write if the
			//      file doesn't exist

		case write:
			flags |= O_WRONLY | O_CREAT | O_TRUNC;
			break;

		case write_safe:
			flags |= O_WRONLY | O_CREAT | O_TRUNC;
			m_filePath = m_filePath.AppendExt(wxT(".new"));
			m_safeWrite = true;
			break;

		case write_excl:
			flags |= O_WRONLY | O_CREAT | O_EXCL;
			break;

		case read_write:
			flags |= O_RDWR;
		break;
	}

	// Windows needs wide character file names
#ifdef __WINDOWS__
	m_fd = _wopen(m_filePath.GetRaw().c_str(), flags, accessMode);
#else
	Unicode2CharBuf tmpFileName = filename2char(m_filePath.GetRaw());
	wxASSERT_MSG(tmpFileName, wxT("Convertion failed in CFile::Open"));
	m_fd = open(tmpFileName, flags, accessMode);
#endif
	syscall_check(m_fd != fd_invalid, m_filePath, wxT("opening file"));

	return IsOpened();
}
Beispiel #14
0
bool CFile::Open(const wxString& fileName, OpenMode mode, int accessMode)
{
	MULE_VALIDATE_PARAMS(fileName.Length(), wxT("CFile: Cannot open, empty path."));

	return Open(CPath(fileName), mode, accessMode);
}
Beispiel #15
0
bool CFile::Open(const wxString& fileName, OpenMode mode, int accessMode)
{
	MULE_VALIDATE_PARAMS(!fileName.IsEmpty(), wxT("CFile: Cannot open, empty path."));

#ifdef __linux__
	int flags = O_BINARY | O_LARGEFILE;
#else
	int flags = O_BINARY;
#endif

	switch ( mode ) {
		case read:
			flags |= O_RDONLY;
			break;
	
		case write_append:
			if (CheckFileExists(fileName))
			{
				flags |= O_WRONLY | O_APPEND;
				break;
			}
			//else: fall through as write_append is the same as write if the
			//      file doesn't exist
	
		case write:
			flags |= O_WRONLY | O_CREAT | O_TRUNC;
			break;
	
		case write_excl:
			flags |= O_WRONLY | O_CREAT | O_EXCL;
			break;

		case read_write:
			flags |= O_RDWR;
        	break;
	}

	if (IsOpened()) {
		Close();	
	}

	
	// When opening files, we will always first try to create an ANSI file name,
	// even if that means an extended ANSI file name. Only if it is not possible
	// to do that, we fall back to  UTF-8 file names. This is unicode safe and is
	// the only way to guarantee that we can open any file in the file system,
	// even if it is not an UTF-8 valid sequence.
	//
	
	
	// Test if it is possible to use an ANSI name
	Unicode2CharBuf tmpFileName = unicode2char(fileName);
	if (tmpFileName) {
		// Use an ANSI name
		m_fd = open(tmpFileName, flags, accessMode);
	} 
	
	if (m_fd == fd_invalid) { // Wrong conversion or can't open.
		// Try an UTF-8 name
		m_fd = open(unicode2UTF8(fileName), flags, accessMode);
	}
	
	m_filePath = fileName;

	SYSCALL_CHECK(m_fd != fd_invalid, wxT("opening file"));	
      
    return IsOpened();
}