// Function taken from Haiku ShowImage, // function originally written by Michael Pfeiffer bool SlideShowSaver::FindNextImage(entry_ref *in_current, entry_ref *out_image, bool next, bool rewind) { // ASSERT(next || !rewind); BEntry curImage(in_current); entry_ref entry, *ref; BDirectory parent; BList entries; bool found = false; int32 cur; if (curImage.GetParent(&parent) != B_OK) return false; while (parent.GetNextRef(&entry) == B_OK) { if (entry != *in_current) { entries.AddItem(new entry_ref(entry)); } else { // insert current ref, so we can find it easily after sorting entries.AddItem(in_current); } } entries.SortItems(CompareEntries); cur = entries.IndexOf(in_current); // ASSERT(cur >= 0); // remove it so FreeEntries() does not delete it entries.RemoveItem(in_current); if (next) { // find the next image in the list if (rewind) cur = 0; // start with first for (; (ref = (entry_ref*)entries.ItemAt(cur)) != NULL; cur ++) { if (IsImage(ref)) { found = true; *out_image = (const entry_ref)*ref; break; } } } else { // find the previous image in the list cur --; for (; cur >= 0; cur --) { ref = (entry_ref*)entries.ItemAt(cur); if (IsImage(ref)) { found = true; *out_image = (const entry_ref)*ref; break; } } } FreeEntries(&entries); return found; }
/** * @return true if the log was loaded successfully. */ BOOL CTextLogFile::LoadEntries(void) { #ifdef _DEBUG DWORD dwStartTime = GetTickCount(); #endif BOOL bResult = FALSE; PCTSTR pszLogFileName = GetLogFileName(); HANDLE hFile = CreateFile(pszLogFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile != INVALID_HANDLE_VALUE) { DWORD dwFileSize = (DWORD)GetFileSize(hFile, NULL); if (dwFileSize == 0) { // ignore empty files CloseHandle(hFile); return TRUE; } DWORD dwBufferSize = min(dwFileSize, g_dwMaxBufferSize); PBYTE pFileBuffer = new BYTE[dwBufferSize]; if (pFileBuffer) { BYTE arrUTF8Preamble[sizeof(g_arrUTF8Preamble)]; DWORD dwWritten = 0; if (ReadFile(hFile, arrUTF8Preamble, sizeof(arrUTF8Preamble), &dwWritten, NULL) && dwWritten == sizeof(arrUTF8Preamble) && memcmp(arrUTF8Preamble, g_arrUTF8Preamble, sizeof(arrUTF8Preamble)) == 0) { bResult = TRUE; DWORD dwCurrentPos = 0, dwLineStart = 0; for (;;) { dwWritten = 0; DWORD dwFreeSize = dwBufferSize - dwCurrentPos; if (! ReadFile(hFile, pFileBuffer + dwCurrentPos, dwFreeSize, &dwWritten, NULL)) goto end; BOOL bEndOfFile = dwWritten < dwFreeSize; dwWritten += dwCurrentPos; dwCurrentPos = 0; if (dwWritten == 0) goto end; for (;;) { if (dwCurrentPos >= dwWritten && ! bEndOfFile) { if (dwLineStart > 0) { dwCurrentPos -= dwLineStart; MoveMemory(pFileBuffer, pFileBuffer + dwLineStart, dwCurrentPos); dwLineStart = 0; } else { dwBufferSize *= 2; PBYTE pNewFileBuffer = new BYTE[dwBufferSize]; if (! pNewFileBuffer) { bResult = FALSE; goto end; } CopyMemory(pNewFileBuffer, pFileBuffer, dwCurrentPos); delete[] pFileBuffer; pFileBuffer = pNewFileBuffer; } break; } if (dwCurrentPos < dwWritten ? pFileBuffer[dwCurrentPos] == '\r' || pFileBuffer[dwCurrentPos] == '\n' : bEndOfFile) { if (dwLineStart < dwCurrentPos && ! AddToTail(pFileBuffer + dwLineStart, dwCurrentPos - dwLineStart, true)) { bResult = FALSE; goto end; } if (dwCurrentPos == dwWritten) // bEndOfFile == TRUE, see condition above { bResult = TRUE; goto end; } dwLineStart = dwCurrentPos + 1; } ++dwCurrentPos; } } } end: if (! bResult) FreeEntries(); delete[] pFileBuffer; } CloseHandle(hFile); } else { DWORD dwLastError = GetLastError(); if (dwLastError == ERROR_FILE_NOT_FOUND || dwLastError == ERROR_PATH_NOT_FOUND || GetFileAttributes(pszLogFileName) == INVALID_FILE_ATTRIBUTES) { bResult = TRUE; // ignore missing files } } #ifdef _DEBUG DWORD dwEndTime = GetTickCount(); TCHAR szMessage[128]; _stprintf_s(szMessage, countof(szMessage), _T("CTextLogFile::LoadEntries(): %lu entries, %lu bytes, %lu milliseconds\r\n"), GetNumEntries(), GetNumBytes(), dwEndTime - dwStartTime); OutputDebugString(szMessage); #endif return bResult; }