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; }
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(); }
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.")); } }
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); }
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); } }
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(); }
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); } }
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; }
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")); } }
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.")); } }
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); }
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; }
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(); }
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); }
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(); }