View Issue Details

IDProjectCategoryView StatusLast Update
0001043Far ManagerViewerpublic2011-04-15 00:37
Reportertheultramage Assigned Toalexy  
PrioritynormalSeverityminorReproducibilityN/A
Status closedResolutionfixed 
Product Version2.0 
Fixed in Version3.0 
Summary0001043: viewing a file on network share causes 40kB/s network spam of QUERY_PATH_INFO SMB requests
DescriptionAs $summary$ says. It seems the code, which polls open files for change numerous times per second, and does not distinguish between the local filesystem (says Sysinternals Process Monitor) and remote shares (says Wireshark).
Additional InformationWhile it seems like a neat idea, how cpu/hdd intensive is it to do this sort of polling? And isn't there a more efficient event mechanism to replace this polling loop?
TagsNo tags attached.
Build1934

Activities

zg

2009-09-08 00:51

developer   bugnote:0004032

[ ] Network drives autorefresh

theultramage

2009-09-08 01:36

reporter   bugnote:0004034

Last edited: 2009-09-08 01:37

This setting is unchecked (always was). The bug does not refer to refreshing of folder contents, it refers to nonstop polling for file size(?) while inside the FAR viewer/editor.

alexy

2009-09-08 22:35

administrator   bugnote:0004050

Polling for file-size should not occur in the editor, are you sure it happens there as well?

alexy

2009-09-08 22:50

administrator   bugnote:0004051

Regarding the viewer, the problem is probably the code below, what this code does is update the viewer when the file is changed - this is what gives far viewer the "tail -f" like feature.
A simple solution would be to add a check for a network drive, but I don't really like such a solution as I personaly use this "tail -f" feature on network drives.
Another solution can be to set a interval for this polling, I don't know if it is good enough though.

    case KEY_IDLE:
    {
      if(ViewFile)
      {
        string strRoot;
        GetPathRoot(strFullFileName, strRoot);
        int DriveType=FAR_GetDriveType(strRoot);
        if (DriveType!=DRIVE_REMOVABLE && !IsDriveTypeCDROM(DriveType))
        {
          FAR_FIND_DATA_EX NewViewFindData;

          if ( !apiGetFindDataEx (strFullFileName,&NewViewFindData) )
            return TRUE;

          fflush(ViewFile);
          vseek(ViewFile,0,SEEK_END);
          __int64 CurFileSize=vtell(ViewFile);
          if (ViewFindData.ftLastWriteTime.dwLowDateTime!=NewViewFindData.ftLastWriteTime.dwLowDateTime ||
              ViewFindData.ftLastWriteTime.dwHighDateTime!=NewViewFindData.ftLastWriteTime.dwHighDateTime ||
              CurFileSize!=FileSize)
          {
            ViewFindData=NewViewFindData;
            FileSize=CurFileSize;
            if (FilePos>FileSize)
              ProcessKey(KEY_CTRLEND);
            else
            {
              __int64 PrevLastPage=LastPage;
              Show();
              if (PrevLastPage && !LastPage)
              {
                ProcessKey(KEY_CTRLEND);
                LastPage=TRUE;
              }
            }
          }
        }
      }
      if (Opt.ViewerEditorClock && HostFileViewer!=NULL && HostFileViewer->IsFullScreen())
        ShowTime(FALSE);
      return(TRUE);
    }

theultramage

2009-09-09 23:56

reporter   bugnote:0004058

> Polling for file-size should not occur in the editor, are you sure it happens there as well?
Yes, my mistake, only the viewer behaves like this. Some sort of configurable polling period, or an event notification system (if exists) would be preferable.

2useven10

2011-03-26 08:51

developer  

viewer.diff (5,523 bytes)   
Index: viewer.hpp
===================================================================
--- viewer.hpp	(revision 5887)
+++ viewer.hpp	(working copy)
@@ -163,7 +163,11 @@
 		bool m_bQuickView;
 
 		UINT DefCodePage;
+
 		int vgetc_ready;
+		__int64 EOF_Pos;
+		int update_check_period;
+		DWORD last_update_check;
 
 	private:
 		virtual void DisplayObject();
Index: viewer.cpp
===================================================================
--- viewer.cpp	(revision 5887)
+++ viewer.cpp	(working copy)
@@ -128,6 +128,7 @@
 	bVE_READ_Sent = false;
 	Signature = false;
 	vgetc_ready = -1;
+   EOF_Pos = -1;
 }
 
 
@@ -376,6 +377,23 @@
 	   ���� �������������� */
 	CtrlObject->Plugins.ProcessViewerEvent(VE_READ,nullptr);
 	bVE_READ_Sent = true;
+
+	last_update_check = GetTickCount();
+	string strRoot;
+	GetPathRoot(strFullFileName, strRoot);
+	int DriveType = FAR_GetDriveType(strRoot);
+	if (IsDriveTypeCDROM(DriveType))
+		DriveType = DRIVE_CDROM;
+	switch (DriveType) //??? make it configurable
+	{
+		case DRIVE_REMOVABLE: update_check_period = -1;   break; // flash drive or floppy: never
+		case DRIVE_FIXED:     update_check_period = +1;   break; // hard disk: 1msec
+		case DRIVE_REMOTE:    update_check_period = 1000; break; // network drive: 1sec
+		case DRIVE_CDROM:     update_check_period = -1;   break; // cd/dvd: never
+		case DRIVE_RAMDISK:   update_check_period = +1;   break; // ramdrive: 1msec
+		default:              update_check_period = -1;   break; // unknown: never
+	}
+
 	return TRUE;
 }
 
@@ -454,7 +472,11 @@
 	if (!SelectSize)
 		SelectPos=FilePos;
 
-	switch (nMode)
+   __int64 last_filepos = -1;
+   bool eof_mode = EOF_Pos >= 0 && nMode == SHOW_RELOAD;
+   do {
+   
+   switch (nMode)
 	{
 		case SHOW_HEX:
 			CtrlObject->Plugins.CurViewer = this; //HostFileViewer;
@@ -473,6 +495,13 @@
 				ReadString(Strings[I],-1,MAX_VIEWLINEB);
 			}
 
+         if (eof_mode)
+         {
+            last_filepos = vtell();
+            eof_mode = last_filepos < EOF_Pos;
+            if (eof_mode)
+               nMode = SHOW_DOWN;
+         }
 			break;
 		case SHOW_UP:
 
@@ -506,8 +535,20 @@
 			ReadString(Strings[Y2-Y1],-1,MAX_VIEWLINEB);
 			Strings[Y2-Y1]->nFilePos = vtell();
 			ReadString(Strings[Y2-Y1],-1,MAX_VIEWLINEB);
+
+         if (eof_mode)
+         {
+            __int64 fpos = vtell();
+            if (fpos >= EOF_Pos || fpos <= last_filepos)
+            {
+               eof_mode = false; nMode = SHOW_RELOAD;
+            }
+            else
+               last_filepos = fpos;
+         }
 			break;
 	}
+   } while ( eof_mode );
 
 	if (nMode != SHOW_HEX)
 	{
@@ -676,7 +717,7 @@
 
 					if (!X)
 					{
-						*OutStr=0;
+						*OutStr = L'\0';
 						break;
 					}
 
@@ -721,7 +762,7 @@
 
 			if (!nr)
 			{
-				*OutStr=0;
+				*OutStr = L'\0';
 			}
 			else
 			{
@@ -816,7 +857,7 @@
 
 					if (!X)
 					{
-						*OutStr=0;
+						*OutStr = L'\0';
 						break;
 					}
 
@@ -1269,42 +1310,39 @@
 		}
 		case KEY_IDLE:
 		{
-			if (ViewFile.Opened())
+			if (ViewFile.Opened() && update_check_period >= 0)
 			{
-				string strRoot;
-				GetPathRoot(strFullFileName, strRoot);
-				int DriveType=FAR_GetDriveType(strRoot);
+				DWORD now_ticks = GetTickCount();
+				if ((int)(now_ticks - last_update_check) < update_check_period)
+					return TRUE;
+				last_update_check = now_ticks;
 
-				if (DriveType!=DRIVE_REMOVABLE && !IsDriveTypeCDROM(DriveType))
-				{
-					FAR_FIND_DATA_EX NewViewFindData;
+				FAR_FIND_DATA_EX NewViewFindData;
+				if (!apiGetFindDataEx(strFullFileName, NewViewFindData))
+					return TRUE;
 
-					if (!apiGetFindDataEx(strFullFileName, NewViewFindData))
-						return TRUE;
+				ViewFile.FlushBuffers();
+				vseek(0,SEEK_END);
+				__int64 CurFileSize=vtell();
 
-					ViewFile.FlushBuffers();
-					vseek(0,SEEK_END);
-					__int64 CurFileSize=vtell();
+				if (ViewFindData.ftLastWriteTime.dwLowDateTime!=NewViewFindData.ftLastWriteTime.dwLowDateTime
+				 || ViewFindData.ftLastWriteTime.dwHighDateTime!=NewViewFindData.ftLastWriteTime.dwHighDateTime
+				 || CurFileSize!=FileSize)
+				{
+					ViewFindData=NewViewFindData;
+					FileSize=CurFileSize;
 
-					if (ViewFindData.ftLastWriteTime.dwLowDateTime!=NewViewFindData.ftLastWriteTime.dwLowDateTime ||
-					        ViewFindData.ftLastWriteTime.dwHighDateTime!=NewViewFindData.ftLastWriteTime.dwHighDateTime ||
-					        CurFileSize!=FileSize)
+					if (FilePos>FileSize)
+						ProcessKey(KEY_CTRLEND);
+					else
 					{
-						ViewFindData=NewViewFindData;
-						FileSize=CurFileSize;
+						__int64 PrevLastPage=LastPage;
+						Show();
 
-						if (FilePos>FileSize)
+						if (PrevLastPage && !LastPage)
+						{
 							ProcessKey(KEY_CTRLEND);
-						else
-						{
-							__int64 PrevLastPage=LastPage;
-							Show();
-
-							if (PrevLastPage && !LastPage)
-							{
-								ProcessKey(KEY_CTRLEND);
-								LastPage=TRUE;
-							}
+							LastPage=TRUE;
 						}
 					}
 				}
@@ -1796,6 +1834,8 @@
 				}
 
 				FilePos=vtell();
+            if (!VM.Hex && VM.Wrap && VM.WordWrap)
+               EOF_Pos = FilePos; //!!! hack to adjust possible incorrect last page show
 
 				/*
 				        {
@@ -1826,6 +1866,7 @@
 				        }
 				*/
 				Show();
+            EOF_Pos = -1;
 //        LastSelPos=FilePos;
 			}
 
viewer.diff (5,523 bytes)   

2useven10

2011-03-26 08:55

developer   bugnote:0006567

Last edited: 2011-03-26 09:07

можно например так...
в аттаче 2 апдэйта (1043, 796).
периоды опроса пока просто зашиты в код - для DRIVE_REMOTE: один раз в секунду
ЗЫ: должны быть табы в индентах (viewer.diff) ...

2useven10

2011-03-27 00:05

developer  

viewer_10.diff (16,011 bytes)   
Index: viewer.hpp
===================================================================
--- viewer.hpp	(revision 5894)
+++ viewer.hpp	(working copy)
@@ -163,7 +163,11 @@
 		bool m_bQuickView;
 
 		UINT DefCodePage;
+
 		int vgetc_ready;
+		__int64 EOF_Pos;
+		int update_check_period;
+		DWORD last_update_check;
 
 	private:
 		virtual void DisplayObject();
Index: cache.cpp
===================================================================
--- cache.cpp	(revision 5894)
+++ cache.cpp	(working copy)
@@ -128,30 +128,39 @@
 	{
 		INT64 Pointer=0;
 		Pointer = file.GetPointer();
-		bool Bidirection=false;
-		if(Pointer>BufferSize/2)
+
+		int shift = (int)Pointer & 0x7ff; // 2k pointer alignment for \\.\CdRom0
+      if (Pointer-shift > BufferSize/2)
+			shift += BufferSize/2;         // suppose BufferSize/2 is 2k aligned...
+
+		if (shift)
+			file.SetPointer(-shift, nullptr, FILE_CURRENT);
+
+      DWORD read_size = BufferSize;
+		UINT64 FileSize = 0;
+		if (file.GetSize(FileSize) && Pointer-shift+BufferSize > (INT64)FileSize)
+			read_size = (DWORD)((INT64)FileSize-Pointer+shift);
+
+		Result = file.Read(Buffer, read_size, ReadSize);
+		if (Result)
 		{
-			Bidirection=true;
-			file.SetPointer(-BufferSize/2, nullptr, FILE_CURRENT);
-		}
-		Result = file.Read(Buffer, BufferSize, ReadSize);
-		if(Result)
-		{
-			BytesLeft = ReadSize;
-			if(Bidirection && BytesLeft>=BufferSize/2)
+			if (ReadSize > (DWORD)shift)
 			{
-				BytesLeft-=BufferSize/2;
+				BytesLeft = ReadSize - shift;
+				file.SetPointer(Pointer, nullptr, FILE_BEGIN);
 			}
-			file.SetPointer(Pointer, nullptr, FILE_BEGIN);
+			else
+				BytesLeft = 0;
 		}
 		else
 		{
-			if (Bidirection)
+			if (shift)
 				file.SetPointer(Pointer, nullptr, FILE_BEGIN);
 			ReadSize=0;
 			BytesLeft=0;
 		}
 	}
+
 	return Result;
 }
 
Index: viewer.cpp
===================================================================
--- viewer.cpp	(revision 5894)
+++ viewer.cpp	(working copy)
@@ -128,6 +128,7 @@
 	bVE_READ_Sent = false;
 	Signature = false;
 	vgetc_ready = -1;
+   EOF_Pos = -1;
 }
 
 
@@ -376,6 +377,31 @@
 	   ���� �������������� */
 	CtrlObject->Plugins.ProcessViewerEvent(VE_READ,nullptr);
 	bVE_READ_Sent = true;
+
+	last_update_check = GetTickCount();
+	string strRoot;
+	GetPathRoot(strFullFileName, strRoot);
+	int DriveType = FAR_GetDriveType(strRoot);
+	if (IsDriveTypeCDROM(DriveType))
+		DriveType = DRIVE_CDROM;
+	switch (DriveType) //??? make it configurable
+	{
+		case DRIVE_REMOVABLE: update_check_period = -1;   break; // flash drive or floppy: never
+		case DRIVE_FIXED:     update_check_period = +1;   break; // hard disk: 1msec
+		case DRIVE_REMOTE:    update_check_period = 1000; break; // network drive: 1sec
+		case DRIVE_CDROM:     update_check_period = -1;   break; // cd/dvd: never
+		case DRIVE_RAMDISK:   update_check_period = +1;   break; // ramdrive: 1msec
+		default:              update_check_period = -1;   break; // unknown: never
+	}
+
+	// �������� �� ���� ����� ���������� ������� ������:
+	//  \\.\C: \\.\D: \\.\PhysucalDrive0 \\.\CdRom0 ....
+	if (INVALID_FILE_ATTRIBUTES == GetFileAttributes(strFullFileName))
+	{
+		DWORD dummy;
+		ViewFile.IoControl(FSCTL_ALLOW_EXTENDED_DASD_IO, NULL,0, NULL,0, &dummy);
+	}
+
 	return TRUE;
 }
 
@@ -454,7 +480,11 @@
 	if (!SelectSize)
 		SelectPos=FilePos;
 
-	switch (nMode)
+   __int64 last_filepos = -1;
+   bool eof_mode = EOF_Pos >= 0 && nMode == SHOW_RELOAD;
+   do {
+   
+   switch (nMode)
 	{
 		case SHOW_HEX:
 			CtrlObject->Plugins.CurViewer = this; //HostFileViewer;
@@ -473,6 +503,13 @@
 				ReadString(Strings[I],-1,MAX_VIEWLINEB);
 			}
 
+         if (eof_mode)
+         {
+            last_filepos = vtell();
+            eof_mode = last_filepos < EOF_Pos;
+            if (eof_mode)
+               nMode = SHOW_DOWN;
+         }
 			break;
 		case SHOW_UP:
 
@@ -506,8 +543,20 @@
 			ReadString(Strings[Y2-Y1],-1,MAX_VIEWLINEB);
 			Strings[Y2-Y1]->nFilePos = vtell();
 			ReadString(Strings[Y2-Y1],-1,MAX_VIEWLINEB);
+
+         if (eof_mode)
+         {
+            __int64 fpos = vtell();
+            if (fpos >= EOF_Pos || fpos <= last_filepos)
+            {
+               eof_mode = false; nMode = SHOW_RELOAD;
+            }
+            else
+               last_filepos = fpos;
+         }
 			break;
 	}
+   } while ( eof_mode );
 
 	if (nMode != SHOW_HEX)
 	{
@@ -598,7 +647,6 @@
 	wchar_t OutStr[MAX_VIEWLINE],TextStr[20];
 	int EndFile;
 	__int64 SelSize;
-	WCHAR Ch;
 	int X,Y,TextPos;
 	int SelStart, SelEnd;
 	bool bSelStartFound = false, bSelEndFound = false;
@@ -640,93 +688,80 @@
 
 		const wchar_t BorderLine[]={BoxSymbols[BS_V1],L' ',0};
 
+		int out_len = (int)wcslen(OutStr);
+		int border_len = (int)wcslen(BorderLine);
+
 		if (IsUnicodeCodePage(VM.CodePage))
 		{
-			for (X=0; X<8; X++)
+			wchar_t line[8];
+			int nr = vread(line, 8);
+			LastPage = EndFile = ViewFile.Eof() ? 1 : 0;
+			if (nr <= 0)
 			{
-				__int64 fpos = vtell();
-
-				if (SelectSize>0 && (SelectPos == fpos))
+				*OutStr = L'\0';
+			}
+			else
+			{
+				for (X=0; X<8; X++)
 				{
-					bSelStartFound = true;
-					SelStart = (int)wcslen(OutStr);
-					SelSize=SelectSize;
-					/* $ 22.01.2001 IS
-					    ��������! ��������, ��� �� ������ ������ ������ �������
-					    ������� �� ��������, �� ��� ���� ������� � ������ �� �����.
-					    � ���������� SelectSize ��� � Process*
-					*/
-					//SelectSize=0;
-				}
-
-				if (SelectSize>0 && (fpos == (SelectPos+SelectSize-1)))
-				{
-					bSelEndFound = true;
-					SelEnd = (int)wcslen(OutStr)+3;
-					SelSize=SelectSize;
-				}
-
-				if (!vgetc(Ch))
-				{
-					/* $ 28.06.2000 tran
-					   ������� ����� ������ ������, ���� �����
-					   ����� ������ 16 */
-					EndFile=1;
-					LastPage=1;
-
-					if (!X)
+					if (SelectSize>0 && (SelectPos == fpos))
 					{
-						*OutStr=0;
-						break;
+						bSelStartFound = true;
+						SelStart = (int)wcslen(OutStr);
+						SelSize=SelectSize;
 					}
-
-					wcscat(OutStr,L"     ");
-					TextStr[TextPos++]=L' ';
-				}
-				else
-				{
-					WCHAR OutChar=Ch;
-
-					if (VM.CodePage == CP_REVERSEBOM)
+					if (SelectSize>0 && (fpos == (SelectPos+SelectSize-1)))
 					{
-						_swab(reinterpret_cast<LPSTR>(&OutChar),reinterpret_cast<LPSTR>(&OutChar),sizeof(WCHAR));
+						bSelEndFound = true;
+						SelEnd = (int)wcslen(OutStr)+3;
+						SelSize=SelectSize;
 					}
 
-					int OutStrLen=StrLength(OutStr);
-					_snwprintf(OutStr+OutStrLen,ARRAYSIZE(OutStr)-OutStrLen,L"%02X%02X ",HIBYTE(OutChar),LOBYTE(OutChar));
-
-					if (!Ch)
+					if (X < nr)
 					{
-						Ch=L' ';
+						unsigned char b1 = HIBYTE(line[X]), b2 = LOBYTE(line[X]);
+#if 0																 // !!! ��������� �������� !!!
+						if (VM.CodePage != CP_REVERSEBOM) // ��� ������ � ���� ����
+						{                                 // ������� �������� ������������� ���
+							unsigned char t = b1; b1 = b2; b2 = t;
+						}
+#endif
+						_snwprintf(OutStr+out_len, ARRAYSIZE(OutStr)-out_len, L"%02X%02X ", b1, b2);
+						TextStr[TextPos++] = line[X] ? line[X] : L' ';
 					}
+					else
+					{
+						wcscpy(OutStr+out_len, L"     ");
+						TextStr[TextPos++] = L' ';
+					}
+					out_len += 5;
 
-					TextStr[TextPos++]=Ch;
-					LastPage=0;
+					if (X == 3)
+					{
+						wcscpy(OutStr+out_len, BorderLine);
+						out_len += border_len;
+					}
 				}
-
-				if (X==3)
-					wcscat(OutStr, BorderLine);
+				++fpos;
 			}
 		}
-		else if ( CP_UTF8 == VM.CodePage )
+		else
 		{
-			__int64 fpos = vtell();
 			unsigned char line[16+3];
 			DWORD nr = 0;
-			Reader.Read(line, (DWORD)sizeof(line), &nr);
+			DWORD nb = CP_UTF8 == VM.CodePage ? 16+3 : 16;
+			Reader.Read(line, nb, &nr);
 			if (nr > 16)
 				Reader.Unread(nr-16);
 
-			LastPage = nr < (DWORD)sizeof(line) && ViewFile.Eof() ? 1 : 0;
+			LastPage = EndFile = (nr <= nb) && ViewFile.Eof() ? 1 : 0;
 
 			if (!nr)
 			{
-				*OutStr=0;
+				*OutStr = L'\0';
 			}
 			else
 			{
-				int out_len = (int)wcslen(OutStr);
-				int border_len = (int)wcslen(BorderLine);
 				if (SelectSize)
 				{
 					if (SelectPos >= fpos && SelectPos < fpos+16)
@@ -755,95 +790,37 @@
 					else
 						wcscpy(OutStr+off, L"   ");
 					TextStr[X] = L' ';
+					if (CP_UTF8 != VM.CodePage && X < (int)nr && line[X])
+						MultiByteToWideChar(VM.CodePage, 0, (LPCSTR)line+X, 1, TextStr+X, 1);
 				}
 
-				wchar_t w1[16], w2[16];
-				int tail, nw, ib=0, iw=0;
-				nw = utf8_to_WideChar((char *)line, (int)nr, w1, w2, 16, tail);
-				bool first = true;
-				while (ib < 16 && iw < nw)
+				if (CP_UTF8 == VM.CodePage)
 				{
-					if (first && w1[iw] == REPLACE_CHAR && w2[iw] == L'?')
+					wchar_t w1[16], w2[16];
+					int tail, nw, ib=0, iw=0;
+					nw = utf8_to_WideChar((char *)line, (int)nr, w1, w2, 16, tail);
+					bool first = true;
+					while (ib < 16 && iw < nw)
 					{
-						TextStr[ib++] = CONTINUE_CHAR; // ��� ����� �� �� ������ ��������� �� '����' utf-8
-					}                                 // �� ������� ��-�� ����� ��� �� ��� ���� �� �����...
-					else
-					{
-						first = false;
-						TextStr[ib++] = w1[iw] ? w1[iw] : L' ';
+						if (first && w1[iw] == REPLACE_CHAR && w2[iw] == L'?')
+						{
+							TextStr[ib++] = CONTINUE_CHAR; // ��� ����� �� �� ������ ��������� �� '����' utf-8
+						}                                 // �� ������� ��-�� ����� ��� �� ��� ���� �� �����...
+						else
+						{
+							first = false;
+							TextStr[ib++] = w1[iw] ? w1[iw] : L' ';
+						}
+						int clen = WideCharToMultiByte(CP_UTF8, 0, w2+iw, 1, NULL,0, NULL,NULL);
+						while (--clen > 0 && ib < 16)
+							TextStr[ib++] = CONTINUE_CHAR;
+						++iw;
 					}
-					int clen = WideCharToMultiByte(CP_UTF8, 0, w2+iw, 1, NULL,0, NULL,NULL);
-					while (--clen > 0 && ib < 16)
-						TextStr[ib++] = CONTINUE_CHAR;
-					++iw;
 				}
 				TextPos = 16;
 			}
 		}
-		else
-		{
-			for (X=0; X<16; X++)
-			{
-				__int64 fpos = vtell();
 
-				if (SelectSize>0 && (SelectPos == fpos))
-				{
-					bSelStartFound = true;
-					SelStart = (int)wcslen(OutStr);
-					SelSize=SelectSize;
-					/* $ 22.01.2001 IS
-					    ��������! ��������, ��� �� ������ ������ ������ �������
-					    ������� �� ��������, �� ��� ���� ������� � ������ �� �����.
-					    � ���������� SelectSize ��� � Process*
-					*/
-					//SelectSize=0;
-				}
-
-				if (SelectSize>0 && (fpos == (SelectPos+SelectSize-1)))
-				{
-					bSelEndFound = true;
-					SelEnd = (int)wcslen(OutStr)+1;
-					SelSize=SelectSize;
-				}
-
-				if (!vgetc(Ch))
-				{
-					/* $ 28.06.2000 tran
-					   ������� ����� ������ ������, ���� �����
-					   ����� ������ 16 */
-					EndFile=1;
-					LastPage=1;
-
-					if (!X)
-					{
-						*OutStr=0;
-						break;
-					}
-
-					/* $ 03.07.2000 tran
-					   - ������ 5 �������� ��� ���� 3 */
-					wcscat(OutStr,L"   ");
-					TextStr[TextPos++]=L' ';
-				}
-				else
-				{
-					char NewCh;
-					WideCharToMultiByte(VM.CodePage, 0, &Ch,1, &NewCh,1," ",nullptr);
-					int OutStrLen=StrLength(OutStr);
-					_snwprintf(OutStr+OutStrLen,ARRAYSIZE(OutStr)-OutStrLen,L"%02X ", NewCh);
-
-					if (!Ch)
-						Ch=L' ';
-
-					TextStr[TextPos++]=Ch;
-					LastPage=0;
-				}
-
-				if (X==7)
-					wcscat(OutStr,BorderLine);
-			}
-		}
-
 		TextStr[TextPos]=0;
 		wcscat(TextStr,L" ");
 
@@ -1269,42 +1246,39 @@
 		}
 		case KEY_IDLE:
 		{
-			if (ViewFile.Opened())
+			if (ViewFile.Opened() && update_check_period >= 0)
 			{
-				string strRoot;
-				GetPathRoot(strFullFileName, strRoot);
-				int DriveType=FAR_GetDriveType(strRoot);
+				DWORD now_ticks = GetTickCount();
+				if ((int)(now_ticks - last_update_check) < update_check_period)
+					return TRUE;
+				last_update_check = now_ticks;
 
-				if (DriveType!=DRIVE_REMOVABLE && !IsDriveTypeCDROM(DriveType))
-				{
-					FAR_FIND_DATA_EX NewViewFindData;
+				FAR_FIND_DATA_EX NewViewFindData;
+				if (!apiGetFindDataEx(strFullFileName, NewViewFindData))
+					return TRUE;
 
-					if (!apiGetFindDataEx(strFullFileName, NewViewFindData))
-						return TRUE;
+				ViewFile.FlushBuffers();
+				vseek(0,SEEK_END);
+				__int64 CurFileSize=vtell();
 
-					ViewFile.FlushBuffers();
-					vseek(0,SEEK_END);
-					__int64 CurFileSize=vtell();
+				if (ViewFindData.ftLastWriteTime.dwLowDateTime!=NewViewFindData.ftLastWriteTime.dwLowDateTime
+				 || ViewFindData.ftLastWriteTime.dwHighDateTime!=NewViewFindData.ftLastWriteTime.dwHighDateTime
+				 || CurFileSize!=FileSize)
+				{
+					ViewFindData=NewViewFindData;
+					FileSize=CurFileSize;
 
-					if (ViewFindData.ftLastWriteTime.dwLowDateTime!=NewViewFindData.ftLastWriteTime.dwLowDateTime ||
-					        ViewFindData.ftLastWriteTime.dwHighDateTime!=NewViewFindData.ftLastWriteTime.dwHighDateTime ||
-					        CurFileSize!=FileSize)
+					if (FilePos>FileSize)
+						ProcessKey(KEY_CTRLEND);
+					else
 					{
-						ViewFindData=NewViewFindData;
-						FileSize=CurFileSize;
+						__int64 PrevLastPage=LastPage;
+						Show();
 
-						if (FilePos>FileSize)
-							ProcessKey(KEY_CTRLEND);
-						else
+						if (PrevLastPage && !LastPage)
 						{
-							__int64 PrevLastPage=LastPage;
-							Show();
-
-							if (PrevLastPage && !LastPage)
-							{
-								ProcessKey(KEY_CTRLEND);
-								LastPage=TRUE;
-							}
+							ProcessKey(KEY_CTRLEND);
+							LastPage=TRUE;
 						}
 					}
 				}
@@ -1785,7 +1759,17 @@
 				unsigned int max_counter=Y2-Y1;
 
 				if (VM.Hex)
+				{
 					vseek(0,SEEK_END);
+					FilePos = vtell();
+					int line_chars = IsUnicodeCodePage(VM.CodePage) ? 8 : 16;
+					if ((FilePos % line_chars) == 0)
+						FilePos -= line_chars * (Y2 - Y1 + 1);
+					else
+						FilePos -= (FilePos % line_chars) + line_chars * (Y2 - Y1);
+					if (FilePos < 0)
+						FilePos = 0;
+				}
 				else
 				{
 					vseek(-1,SEEK_END);
@@ -1793,39 +1777,17 @@
 
 					if (vgetc(LastSym) && LastSym!=CRSym)
 						++max_counter;
-				}
 
-				FilePos=vtell();
+					FilePos=vtell();
+		         if (VM.Wrap && VM.WordWrap)
+			         EOF_Pos = FilePos; //!!! hack to adjust possible incorrect last page show
 
-				/*
-				        {
-				          char Buf[100];
-				          sprintf(Buf,"%I64X",FilePos);
-				          Message(0,1,"End",Buf,"Ok");
-				        }
-				*/
-				for (int i=0; static_cast<unsigned int>(i)<max_counter; i++)
-					Up();
+					for (int i=0; static_cast<unsigned int>(i)<max_counter; i++)
+						Up();
+				}
 
-				/*
-				        {
-				          char Buf[100];
-				          sprintf(Buf,"%I64X, %d",FilePos, I);
-				          Message(0,1,"Up",Buf,"Ok");
-				        }
-				*/
-				if (VM.Hex)
-					FilePos&=~(IsUnicodeCodePage(VM.CodePage) ? 0x7:0xf);
-
-				/*
-				        if (VM.Hex)
-				        {
-				          char Buf[100];
-				          sprintf(Buf,"%I64X",FilePos);
-				          Message(0,1,"VM.Hex",Buf,"Ok");
-				        }
-				*/
 				Show();
+            EOF_Pos = -1;
 //        LastSelPos=FilePos;
 			}
 
@@ -3003,14 +2965,12 @@
 	}
 }
 
-
 int Viewer::vseek(__int64 Offset,int Whence)
 {
 	vgetc_ready = -1;
 	return ViewFile.SetPointer(Offset*(IsUnicodeCodePage(VM.CodePage)?2:1), nullptr, Whence);
 }
 
-
 __int64 Viewer::vtell()
 {
 	INT64 Ptr=ViewFile.GetPointer();
@@ -3021,7 +2981,6 @@
 	return Ptr;
 }
 
-
 bool Viewer::vgetc(WCHAR& C)
 {
 	bool Result;
@@ -3059,7 +3018,6 @@
 	return Result;
 }
 
-
 #define RB_PRC 3
 #define RB_HEX 4
 #define RB_DEC 5
viewer_10.diff (16,011 bytes)   

2useven10

2011-03-27 00:09

developer   bugnote:0006569

Last edited: 2011-03-27 00:11

viewer_10.diff содержит все мои незакоммиченные изменения для вьювера.
не только для 1043, но также фиксы для hex-view и просмотра спец-файлов
(\\.\C: \\.\PhysicalDrive0 .....)
Просто для этих багов соответствующие мантисы закрыты...
изменения для фар2 как обычно: http://sharapov-16.narod.ru/far/index.html

DrKnS

2011-03-27 08:21

administrator   bugnote:0006570

> int shift = (int)Pointer & 0x7ff; // 2k pointer alignment for \\.\CdRom0

У новых жестких дисков сектора по 4k.

2useven10

2011-03-27 09:17

developer   bugnote:0006572

Last edited: 2011-03-27 09:38

не знал... поправлю

viewer_11.diff -- выравнивание позиционирования на 4k

DrKnS

2011-03-27 09:32

administrator   bugnote:0006574

кстати, раз мы читаем по 64к, может быть и прыгать имеет смысл на 64к-границу?
При рандомном листании читаться будут всё время одни и те же куски и (теоретически) ос может это как-то кешировать и оптимизировать.

2useven10

2011-03-27 09:36

developer  

viewer_11.diff (16,055 bytes)   
Index: viewer.hpp
===================================================================
--- viewer.hpp	(revision 5894)
+++ viewer.hpp	(working copy)
@@ -163,7 +163,11 @@
 		bool m_bQuickView;
 
 		UINT DefCodePage;
+
 		int vgetc_ready;
+		__int64 EOF_Pos;
+		int update_check_period;
+		DWORD last_update_check;
 
 	private:
 		virtual void DisplayObject();
Index: cache.cpp
===================================================================
--- cache.cpp	(revision 5894)
+++ cache.cpp	(working copy)
@@ -128,30 +128,39 @@
 	{
 		INT64 Pointer=0;
 		Pointer = file.GetPointer();
-		bool Bidirection=false;
-		if(Pointer>BufferSize/2)
+
+		int shift = (int)Pointer & 0xfff; // 4k pointer alignment (some new disks has 4k sector size)
+      if (Pointer-shift > BufferSize/2)
+			shift += BufferSize/2;         // suppose BufferSize/2 is 4k aligned...
+
+		if (shift)
+			file.SetPointer(-shift, nullptr, FILE_CURRENT);
+
+      DWORD read_size = BufferSize;
+		UINT64 FileSize = 0;
+		if (file.GetSize(FileSize) && Pointer-shift+BufferSize > (INT64)FileSize)
+			read_size = (DWORD)((INT64)FileSize-Pointer+shift);
+
+		Result = file.Read(Buffer, read_size, ReadSize);
+		if (Result)
 		{
-			Bidirection=true;
-			file.SetPointer(-BufferSize/2, nullptr, FILE_CURRENT);
-		}
-		Result = file.Read(Buffer, BufferSize, ReadSize);
-		if(Result)
-		{
-			BytesLeft = ReadSize;
-			if(Bidirection && BytesLeft>=BufferSize/2)
+			if (ReadSize > (DWORD)shift)
 			{
-				BytesLeft-=BufferSize/2;
+				BytesLeft = ReadSize - shift;
+				file.SetPointer(Pointer, nullptr, FILE_BEGIN);
 			}
-			file.SetPointer(Pointer, nullptr, FILE_BEGIN);
+			else
+				BytesLeft = 0;
 		}
 		else
 		{
-			if (Bidirection)
+			if (shift)
 				file.SetPointer(Pointer, nullptr, FILE_BEGIN);
 			ReadSize=0;
 			BytesLeft=0;
 		}
 	}
+
 	return Result;
 }
 
Index: viewer.cpp
===================================================================
--- viewer.cpp	(revision 5894)
+++ viewer.cpp	(working copy)
@@ -128,6 +128,7 @@
 	bVE_READ_Sent = false;
 	Signature = false;
 	vgetc_ready = -1;
+   EOF_Pos = -1;
 }
 
 
@@ -376,6 +377,31 @@
 	   ���� �������������� */
 	CtrlObject->Plugins.ProcessViewerEvent(VE_READ,nullptr);
 	bVE_READ_Sent = true;
+
+	last_update_check = GetTickCount();
+	string strRoot;
+	GetPathRoot(strFullFileName, strRoot);
+	int DriveType = FAR_GetDriveType(strRoot);
+	if (IsDriveTypeCDROM(DriveType))
+		DriveType = DRIVE_CDROM;
+	switch (DriveType) //??? make it configurable
+	{
+		case DRIVE_REMOVABLE: update_check_period = -1;   break; // flash drive or floppy: never
+		case DRIVE_FIXED:     update_check_period = +1;   break; // hard disk: 1msec
+		case DRIVE_REMOTE:    update_check_period = 1000; break; // network drive: 1sec
+		case DRIVE_CDROM:     update_check_period = -1;   break; // cd/dvd: never
+		case DRIVE_RAMDISK:   update_check_period = +1;   break; // ramdrive: 1msec
+		default:              update_check_period = -1;   break; // unknown: never
+	}
+
+	// �������� �� ���� ����� ���������� ������� ������:
+	//  \\.\C: \\.\D: \\.\PhysucalDrive0 \\.\CdRom0 \\?\Volume{Volume_GUID} ...
+	if (INVALID_FILE_ATTRIBUTES == GetFileAttributes(strFullFileName))
+	{
+		DWORD dummy;
+		ViewFile.IoControl(FSCTL_ALLOW_EXTENDED_DASD_IO, NULL,0, NULL,0, &dummy);
+	}
+
 	return TRUE;
 }
 
@@ -454,7 +480,11 @@
 	if (!SelectSize)
 		SelectPos=FilePos;
 
-	switch (nMode)
+   __int64 last_filepos = -1;
+   bool eof_mode = EOF_Pos >= 0 && nMode == SHOW_RELOAD;
+   do {
+   
+   switch (nMode)
 	{
 		case SHOW_HEX:
 			CtrlObject->Plugins.CurViewer = this; //HostFileViewer;
@@ -473,6 +503,13 @@
 				ReadString(Strings[I],-1,MAX_VIEWLINEB);
 			}
 
+         if (eof_mode)
+         {
+            last_filepos = vtell();
+            eof_mode = last_filepos < EOF_Pos;
+            if (eof_mode)
+               nMode = SHOW_DOWN;
+         }
 			break;
 		case SHOW_UP:
 
@@ -506,8 +543,20 @@
 			ReadString(Strings[Y2-Y1],-1,MAX_VIEWLINEB);
 			Strings[Y2-Y1]->nFilePos = vtell();
 			ReadString(Strings[Y2-Y1],-1,MAX_VIEWLINEB);
+
+         if (eof_mode)
+         {
+            __int64 fpos = vtell();
+            if (fpos >= EOF_Pos || fpos <= last_filepos)
+            {
+               eof_mode = false; nMode = SHOW_RELOAD;
+            }
+            else
+               last_filepos = fpos;
+         }
 			break;
 	}
+   } while ( eof_mode );
 
 	if (nMode != SHOW_HEX)
 	{
@@ -598,7 +647,6 @@
 	wchar_t OutStr[MAX_VIEWLINE],TextStr[20];
 	int EndFile;
 	__int64 SelSize;
-	WCHAR Ch;
 	int X,Y,TextPos;
 	int SelStart, SelEnd;
 	bool bSelStartFound = false, bSelEndFound = false;
@@ -640,93 +688,80 @@
 
 		const wchar_t BorderLine[]={BoxSymbols[BS_V1],L' ',0};
 
+		int out_len = (int)wcslen(OutStr);
+		int border_len = (int)wcslen(BorderLine);
+
 		if (IsUnicodeCodePage(VM.CodePage))
 		{
-			for (X=0; X<8; X++)
+			wchar_t line[8];
+			int nr = vread(line, 8);
+			LastPage = EndFile = ViewFile.Eof() ? 1 : 0;
+			if (nr <= 0)
 			{
-				__int64 fpos = vtell();
-
-				if (SelectSize>0 && (SelectPos == fpos))
+				*OutStr = L'\0';
+			}
+			else
+			{
+				for (X=0; X<8; X++)
 				{
-					bSelStartFound = true;
-					SelStart = (int)wcslen(OutStr);
-					SelSize=SelectSize;
-					/* $ 22.01.2001 IS
-					    ��������! ��������, ��� �� ������ ������ ������ �������
-					    ������� �� ��������, �� ��� ���� ������� � ������ �� �����.
-					    � ���������� SelectSize ��� � Process*
-					*/
-					//SelectSize=0;
-				}
-
-				if (SelectSize>0 && (fpos == (SelectPos+SelectSize-1)))
-				{
-					bSelEndFound = true;
-					SelEnd = (int)wcslen(OutStr)+3;
-					SelSize=SelectSize;
-				}
-
-				if (!vgetc(Ch))
-				{
-					/* $ 28.06.2000 tran
-					   ������� ����� ������ ������, ���� �����
-					   ����� ������ 16 */
-					EndFile=1;
-					LastPage=1;
-
-					if (!X)
+					if (SelectSize>0 && (SelectPos == fpos))
 					{
-						*OutStr=0;
-						break;
+						bSelStartFound = true;
+						SelStart = (int)wcslen(OutStr);
+						SelSize=SelectSize;
 					}
-
-					wcscat(OutStr,L"     ");
-					TextStr[TextPos++]=L' ';
-				}
-				else
-				{
-					WCHAR OutChar=Ch;
-
-					if (VM.CodePage == CP_REVERSEBOM)
+					if (SelectSize>0 && (fpos == (SelectPos+SelectSize-1)))
 					{
-						_swab(reinterpret_cast<LPSTR>(&OutChar),reinterpret_cast<LPSTR>(&OutChar),sizeof(WCHAR));
+						bSelEndFound = true;
+						SelEnd = (int)wcslen(OutStr)+3;
+						SelSize=SelectSize;
 					}
 
-					int OutStrLen=StrLength(OutStr);
-					_snwprintf(OutStr+OutStrLen,ARRAYSIZE(OutStr)-OutStrLen,L"%02X%02X ",HIBYTE(OutChar),LOBYTE(OutChar));
-
-					if (!Ch)
+					if (X < nr)
 					{
-						Ch=L' ';
+						unsigned char b1 = HIBYTE(line[X]), b2 = LOBYTE(line[X]);
+#if 0																 // !!! ��������� �������� !!!
+						if (VM.CodePage != CP_REVERSEBOM) // ��� ������ � ���� ����
+						{                                 // ������� �������� ������������� ���
+							unsigned char t = b1; b1 = b2; b2 = t;
+						}
+#endif
+						_snwprintf(OutStr+out_len, ARRAYSIZE(OutStr)-out_len, L"%02X%02X ", b1, b2);
+						TextStr[TextPos++] = line[X] ? line[X] : L' ';
 					}
+					else
+					{
+						wcscpy(OutStr+out_len, L"     ");
+						TextStr[TextPos++] = L' ';
+					}
+					out_len += 5;
 
-					TextStr[TextPos++]=Ch;
-					LastPage=0;
+					if (X == 3)
+					{
+						wcscpy(OutStr+out_len, BorderLine);
+						out_len += border_len;
+					}
 				}
-
-				if (X==3)
-					wcscat(OutStr, BorderLine);
+				++fpos;
 			}
 		}
-		else if ( CP_UTF8 == VM.CodePage )
+		else
 		{
-			__int64 fpos = vtell();
 			unsigned char line[16+3];
 			DWORD nr = 0;
-			Reader.Read(line, (DWORD)sizeof(line), &nr);
+			DWORD nb = CP_UTF8 == VM.CodePage ? 16+3 : 16;
+			Reader.Read(line, nb, &nr);
 			if (nr > 16)
 				Reader.Unread(nr-16);
 
-			LastPage = nr < (DWORD)sizeof(line) && ViewFile.Eof() ? 1 : 0;
+			LastPage = EndFile = (nr <= nb) && ViewFile.Eof() ? 1 : 0;
 
 			if (!nr)
 			{
-				*OutStr=0;
+				*OutStr = L'\0';
 			}
 			else
 			{
-				int out_len = (int)wcslen(OutStr);
-				int border_len = (int)wcslen(BorderLine);
 				if (SelectSize)
 				{
 					if (SelectPos >= fpos && SelectPos < fpos+16)
@@ -755,95 +790,37 @@
 					else
 						wcscpy(OutStr+off, L"   ");
 					TextStr[X] = L' ';
+					if (CP_UTF8 != VM.CodePage && X < (int)nr && line[X])
+						MultiByteToWideChar(VM.CodePage, 0, (LPCSTR)line+X, 1, TextStr+X, 1);
 				}
 
-				wchar_t w1[16], w2[16];
-				int tail, nw, ib=0, iw=0;
-				nw = utf8_to_WideChar((char *)line, (int)nr, w1, w2, 16, tail);
-				bool first = true;
-				while (ib < 16 && iw < nw)
+				if (CP_UTF8 == VM.CodePage)
 				{
-					if (first && w1[iw] == REPLACE_CHAR && w2[iw] == L'?')
+					wchar_t w1[16], w2[16];
+					int tail, nw, ib=0, iw=0;
+					nw = utf8_to_WideChar((char *)line, (int)nr, w1, w2, 16, tail);
+					bool first = true;
+					while (ib < 16 && iw < nw)
 					{
-						TextStr[ib++] = CONTINUE_CHAR; // ��� ����� �� �� ������ ��������� �� '����' utf-8
-					}                                 // �� ������� ��-�� ����� ��� �� ��� ���� �� �����...
-					else
-					{
-						first = false;
-						TextStr[ib++] = w1[iw] ? w1[iw] : L' ';
+						if (first && w1[iw] == REPLACE_CHAR && w2[iw] == L'?')
+						{
+							TextStr[ib++] = CONTINUE_CHAR; // ��� ����� �� �� ������ ��������� �� '����' utf-8
+						}                                 // �� ������� ��-�� ����� ��� �� ��� ���� �� �����...
+						else
+						{
+							first = false;
+							TextStr[ib++] = w1[iw] ? w1[iw] : L' ';
+						}
+						int clen = WideCharToMultiByte(CP_UTF8, 0, w2+iw, 1, NULL,0, NULL,NULL);
+						while (--clen > 0 && ib < 16)
+							TextStr[ib++] = CONTINUE_CHAR;
+						++iw;
 					}
-					int clen = WideCharToMultiByte(CP_UTF8, 0, w2+iw, 1, NULL,0, NULL,NULL);
-					while (--clen > 0 && ib < 16)
-						TextStr[ib++] = CONTINUE_CHAR;
-					++iw;
 				}
 				TextPos = 16;
 			}
 		}
-		else
-		{
-			for (X=0; X<16; X++)
-			{
-				__int64 fpos = vtell();
 
-				if (SelectSize>0 && (SelectPos == fpos))
-				{
-					bSelStartFound = true;
-					SelStart = (int)wcslen(OutStr);
-					SelSize=SelectSize;
-					/* $ 22.01.2001 IS
-					    ��������! ��������, ��� �� ������ ������ ������ �������
-					    ������� �� ��������, �� ��� ���� ������� � ������ �� �����.
-					    � ���������� SelectSize ��� � Process*
-					*/
-					//SelectSize=0;
-				}
-
-				if (SelectSize>0 && (fpos == (SelectPos+SelectSize-1)))
-				{
-					bSelEndFound = true;
-					SelEnd = (int)wcslen(OutStr)+1;
-					SelSize=SelectSize;
-				}
-
-				if (!vgetc(Ch))
-				{
-					/* $ 28.06.2000 tran
-					   ������� ����� ������ ������, ���� �����
-					   ����� ������ 16 */
-					EndFile=1;
-					LastPage=1;
-
-					if (!X)
-					{
-						*OutStr=0;
-						break;
-					}
-
-					/* $ 03.07.2000 tran
-					   - ������ 5 �������� ��� ���� 3 */
-					wcscat(OutStr,L"   ");
-					TextStr[TextPos++]=L' ';
-				}
-				else
-				{
-					char NewCh;
-					WideCharToMultiByte(VM.CodePage, 0, &Ch,1, &NewCh,1," ",nullptr);
-					int OutStrLen=StrLength(OutStr);
-					_snwprintf(OutStr+OutStrLen,ARRAYSIZE(OutStr)-OutStrLen,L"%02X ", NewCh);
-
-					if (!Ch)
-						Ch=L' ';
-
-					TextStr[TextPos++]=Ch;
-					LastPage=0;
-				}
-
-				if (X==7)
-					wcscat(OutStr,BorderLine);
-			}
-		}
-
 		TextStr[TextPos]=0;
 		wcscat(TextStr,L" ");
 
@@ -1269,42 +1246,39 @@
 		}
 		case KEY_IDLE:
 		{
-			if (ViewFile.Opened())
+			if (ViewFile.Opened() && update_check_period >= 0)
 			{
-				string strRoot;
-				GetPathRoot(strFullFileName, strRoot);
-				int DriveType=FAR_GetDriveType(strRoot);
+				DWORD now_ticks = GetTickCount();
+				if ((int)(now_ticks - last_update_check) < update_check_period)
+					return TRUE;
+				last_update_check = now_ticks;
 
-				if (DriveType!=DRIVE_REMOVABLE && !IsDriveTypeCDROM(DriveType))
-				{
-					FAR_FIND_DATA_EX NewViewFindData;
+				FAR_FIND_DATA_EX NewViewFindData;
+				if (!apiGetFindDataEx(strFullFileName, NewViewFindData))
+					return TRUE;
 
-					if (!apiGetFindDataEx(strFullFileName, NewViewFindData))
-						return TRUE;
+				ViewFile.FlushBuffers();
+				vseek(0,SEEK_END);
+				__int64 CurFileSize=vtell();
 
-					ViewFile.FlushBuffers();
-					vseek(0,SEEK_END);
-					__int64 CurFileSize=vtell();
+				if (ViewFindData.ftLastWriteTime.dwLowDateTime!=NewViewFindData.ftLastWriteTime.dwLowDateTime
+				 || ViewFindData.ftLastWriteTime.dwHighDateTime!=NewViewFindData.ftLastWriteTime.dwHighDateTime
+				 || CurFileSize!=FileSize)
+				{
+					ViewFindData=NewViewFindData;
+					FileSize=CurFileSize;
 
-					if (ViewFindData.ftLastWriteTime.dwLowDateTime!=NewViewFindData.ftLastWriteTime.dwLowDateTime ||
-					        ViewFindData.ftLastWriteTime.dwHighDateTime!=NewViewFindData.ftLastWriteTime.dwHighDateTime ||
-					        CurFileSize!=FileSize)
+					if (FilePos>FileSize)
+						ProcessKey(KEY_CTRLEND);
+					else
 					{
-						ViewFindData=NewViewFindData;
-						FileSize=CurFileSize;
+						__int64 PrevLastPage=LastPage;
+						Show();
 
-						if (FilePos>FileSize)
-							ProcessKey(KEY_CTRLEND);
-						else
+						if (PrevLastPage && !LastPage)
 						{
-							__int64 PrevLastPage=LastPage;
-							Show();
-
-							if (PrevLastPage && !LastPage)
-							{
-								ProcessKey(KEY_CTRLEND);
-								LastPage=TRUE;
-							}
+							ProcessKey(KEY_CTRLEND);
+							LastPage=TRUE;
 						}
 					}
 				}
@@ -1785,7 +1759,17 @@
 				unsigned int max_counter=Y2-Y1;
 
 				if (VM.Hex)
+				{
 					vseek(0,SEEK_END);
+					FilePos = vtell();
+					int line_chars = IsUnicodeCodePage(VM.CodePage) ? 8 : 16;
+					if ((FilePos % line_chars) == 0)
+						FilePos -= line_chars * (Y2 - Y1 + 1);
+					else
+						FilePos -= (FilePos % line_chars) + line_chars * (Y2 - Y1);
+					if (FilePos < 0)
+						FilePos = 0;
+				}
 				else
 				{
 					vseek(-1,SEEK_END);
@@ -1793,39 +1777,17 @@
 
 					if (vgetc(LastSym) && LastSym!=CRSym)
 						++max_counter;
-				}
 
-				FilePos=vtell();
+					FilePos=vtell();
+		         if (VM.Wrap && VM.WordWrap)
+			         EOF_Pos = FilePos; //!!! hack to adjust possible incorrect last page show
 
-				/*
-				        {
-				          char Buf[100];
-				          sprintf(Buf,"%I64X",FilePos);
-				          Message(0,1,"End",Buf,"Ok");
-				        }
-				*/
-				for (int i=0; static_cast<unsigned int>(i)<max_counter; i++)
-					Up();
+					for (int i=0; static_cast<unsigned int>(i)<max_counter; i++)
+						Up();
+				}
 
-				/*
-				        {
-				          char Buf[100];
-				          sprintf(Buf,"%I64X, %d",FilePos, I);
-				          Message(0,1,"Up",Buf,"Ok");
-				        }
-				*/
-				if (VM.Hex)
-					FilePos&=~(IsUnicodeCodePage(VM.CodePage) ? 0x7:0xf);
-
-				/*
-				        if (VM.Hex)
-				        {
-				          char Buf[100];
-				          sprintf(Buf,"%I64X",FilePos);
-				          Message(0,1,"VM.Hex",Buf,"Ok");
-				        }
-				*/
 				Show();
+            EOF_Pos = -1;
 //        LastSelPos=FilePos;
 			}
 
@@ -3003,14 +2965,12 @@
 	}
 }
 
-
 int Viewer::vseek(__int64 Offset,int Whence)
 {
 	vgetc_ready = -1;
 	return ViewFile.SetPointer(Offset*(IsUnicodeCodePage(VM.CodePage)?2:1), nullptr, Whence);
 }
 
-
 __int64 Viewer::vtell()
 {
 	INT64 Ptr=ViewFile.GetPointer();
@@ -3021,7 +2981,6 @@
 	return Ptr;
 }
 
-
 bool Viewer::vgetc(WCHAR& C)
 {
 	bool Result;
@@ -3059,7 +3018,6 @@
 	return Result;
 }
 
-
 #define RB_PRC 3
 #define RB_HEX 4
 #define RB_DEC 5
viewer_11.diff (16,055 bytes)   

2useven10

2011-03-27 09:41

developer   bugnote:0006575

рандомное чтение для просмотра скорее исключение, чем правило.
а при последовательном чтении поведение не изменится.
я думаю овчинка не стоит выделки (если конечно 'совсем новые' диски
не появятся с секторами по 64к :)

zg

2011-03-27 10:46

developer   bugnote:0006577

вообще-то кроме жёстких дисков существует куча всякой экзотики. закладыватся на то, что сектор будет всегда не более чем 4k мне кажется неправильным.

2useven10

2011-03-27 14:28

developer   bugnote:0006578

Last edited: 2011-03-27 14:35

Можно и конфигурить... (причем сначала размер буфера, а потом выравнивание)
Но вообще 4к - это уже размер страницы памяти (в типичном случае).
В msdn было еще упоминание и о выравнивании буфера, на размер сектора.
Но почему-то работает и без этого (возможно я просто читал старую статью).
Пока страница 4к - можно не заморачиваться (IMHO).
И кстати у флэш-драйвов 'сектор' больше чем 4к, но работать будет...
Я надеюсь (кстати кто-нибудь проверял?)

alexy

2011-03-27 14:41

administrator   bugnote:0006579

Можно же через GetDiskFreeSpace получить размер кластера.
Типа как в FTP:

static unsigned get_cluster_size(const char *fname)
{
    char root[MAX_PATH];

    if(GetFullPathName(fname, ARRAYSIZE(root), root, NULL)
            && root[1] == ':' && root[2] == '\\')
    {
        DWORD t1, t2, bps = 0, spc = 0;
        root[3] = '\0';
        spc = bps = 0;

        if(GetDiskFreeSpace(root, &spc, &bps, &t1, &t2)) return(spc*bps);
    }

    return(0);
}

2useven10

2011-03-27 14:51

developer   bugnote:0006580

Не уверен, что прокатит. Но что-нибудь вроде DeviceIoControl(GET_DRIVE_GEOMETRY...) работать будет (имя приблизительное).

zg

2011-03-27 19:26

developer   bugnote:0006581

> Пока страница 4к
вообще-то существовали windows со страницей 8k.

alexy

2011-03-27 21:56

administrator   bugnote:0006582

1934

alexy

2011-03-27 21:56

administrator   bugnote:0006583

1934

2useven10

2011-03-27 22:36

developer   bugnote:0006585

я же написал (в типичном случае). nix-ы c 8k страницами и сейчас не редкость...
но это так треп, я согласен - закладываться на 4к не стоит. код который проверяет размер сектора я уже написал - работает, но попутно я правлю вьювер - пока не закончил (надоело разбирать код, решил переписать up/down). хотел закончить с этим сегодня... не успел

2useven10

2011-03-30 09:17

developer   bugnote:0006640

общий патч: http://bugs.farmanager.com/view.php?id=1031#bugnotes

Issue History

Date Modified Username Field Change
2009-09-07 22:36 theultramage New Issue
2009-09-08 00:51 zg Note Added: 0004032
2009-09-08 01:36 theultramage Note Added: 0004034
2009-09-08 01:37 theultramage Note Edited: 0004034
2009-09-08 22:35 alexy Note Added: 0004050
2009-09-08 22:50 alexy Note Added: 0004051
2009-09-09 23:56 theultramage Note Added: 0004058
2010-02-15 17:09 alexy Category File System => Viewer
2010-02-15 17:09 alexy Summary opening file on network share causes 40kB/s network spam of QUERY_PATH_INFO SMB requests => viewing a file on network share causes 40kB/s network spam of QUERY_PATH_INFO SMB requests
2010-02-16 07:59 alexy Status new => assigned
2010-02-16 07:59 alexy Assigned To => alexy
2011-03-26 08:51 2useven10 File Added: viewer.diff
2011-03-26 08:55 2useven10 Note Added: 0006567
2011-03-26 08:57 2useven10 Note Edited: 0006567
2011-03-26 09:07 2useven10 Note Edited: 0006567
2011-03-27 00:05 2useven10 File Added: viewer_10.diff
2011-03-27 00:09 2useven10 Note Added: 0006569
2011-03-27 00:10 2useven10 Note Edited: 0006569
2011-03-27 00:10 2useven10 Note Edited: 0006569
2011-03-27 00:11 2useven10 Note Edited: 0006569
2011-03-27 08:21 DrKnS Note Added: 0006570
2011-03-27 09:17 2useven10 Note Added: 0006572
2011-03-27 09:32 DrKnS Note Added: 0006574
2011-03-27 09:36 2useven10 File Added: viewer_11.diff
2011-03-27 09:38 2useven10 Note Edited: 0006572
2011-03-27 09:41 2useven10 Note Added: 0006575
2011-03-27 10:46 zg Note Added: 0006577
2011-03-27 14:28 2useven10 Note Added: 0006578
2011-03-27 14:35 2useven10 Note Edited: 0006578
2011-03-27 14:41 alexy Note Added: 0006579
2011-03-27 14:51 2useven10 Note Added: 0006580
2011-03-27 19:26 zg Note Added: 0006581
2011-03-27 21:56 alexy Note Added: 0006582
2011-03-27 21:56 alexy Status assigned => feedback
2011-03-27 21:56 alexy Note Added: 0006583
2011-03-27 22:36 2useven10 Note Added: 0006585
2011-03-30 09:17 2useven10 Note Added: 0006640
2011-04-15 00:37 alexy Build => 1934
2011-04-15 00:37 alexy Status feedback => closed
2011-04-15 00:37 alexy Resolution open => fixed
2011-04-15 00:37 alexy Fixed in Version => 3.0