Re: [fpc-pascal] Parse unicode scalar

2023-07-03 Thread José Mejuto via fpc-pascal

El 03/07/2023 a las 10:27, Hairy Pixels via fpc-pascal escribió:


Right now I've just read the file into an AnsiString and indexing assuming a 
fixed character size, which breaks of course if non-1 byte characters exist

  I also need to know if I come across something like \u1F496 I need to convert 
that to a unicode character.



Hello,

You are intermixing a lot of concepts, ASCII, Unicode, grapheme, 
representation, content, etc...


Talking about Unicode you must forget ASCII, the text is a sequence of 
bytes which are encoded in a special format (UTF-8, UTF-16, UTF-32,...) 
and that must be represented in screen using Unicode representation 
rules, which are not the same as ASCII.


Just to keep this message quite short, think in a text with only one 
"letter":


"á"

This text (text, not one letter, Unicode is about texts) can be 
transmitted or stored using Unicode encoding rules which are a sequence 
of bytes with its own rules to encode the information. Each byte is 
hexadecimal:


UTF8: C3 A1
UTF16LE: 00 E1
UTF32: 00 00 00 E1

You must know in advance the encoding format to get the text from the 
bytes sequence. There is also a BOM (Byte Order Mark) which is sometimes 
used in files as a header to indicate the encoding, but in general it is 
not used.


Now decoding that sequence of bytes, using the right decoding format you 
get a text which represent the letter "a" with an acute accent, but 
Unicode is *not* so *simple* and the same text could be represented in 
screen using letter "a" + "combining acute accent" and bytes sequence is 
totally different, different at encoding level but identical at 
renderization level. So this two UTF8 sequences:


"C3 A1" and "61 CC 81"

are different at grapheme level and encoding level but identical at 
representation level.


Just as final note, this is the UTF-8 sequence of bytes for one single 
"character" in screen:


F0 9F 8F B4 F3 A0 81 A7 F3 A0 81 A2 F3 A0 81 B3 F3 A0 81 A3 F3 A0 81 B4 
F3 A0 81 BF


Unicode is far, far from easy.

Have a nice day.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] SetFileTime

2023-05-03 Thread José Mejuto via fpc-pascal

El 03/05/2023 a las 8:48, Carsten Bager via fpc-pascal escribió:
> I am trying to change the file date on a SYMLINK (not the file that  the
> link points to).
> Does anyone know if there is a method for this under Windows.
> Carsten


Hello,

Attached is a dirty implementation of "touch" for junctions that I need 
in the past. I think it can help you to do the same over other kind of 
links.


Have a nice day.
program touchjunction;

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Classes, SysUtils, windows, CustApp
  { you can add units after this };

const
   FILE_FLAG_OPEN_REPARSE_POINT=DWORD($0020);
   FileTimeBase  = -109205.0;
   FileTimeStep: Extended = 24.0 * 60.0 * 60.0 * 1000.0 * 1000.0 * 10.0; // 100 
nSek per Day

type

  { TTouchJunction }

  TTouchJunction = class(TCustomApplication)
  protected
procedure DoRun; override;
function DateTimeToFileTime(DateTime: TDateTime): TFileTime;
  public
constructor Create(TheOwner: TComponent); override;
destructor Destroy; override;
procedure WriteHelp; virtual;
  end;

{ TTouchJunction }

function TTouchJunction.DateTimeToFileTime(DateTime: TDateTime): TFileTime;
var sysTime: TSYSTEMTIME;
temp: TFILETIME;
begin
  DateTimeToSystemTime(DateTime,sysTime);
  SystemTimeToFileTime(@sysTime,@temp);
  LocalFileTimeToFileTime(@temp,@result);
end;
procedure TTouchJunction.DoRun;
var
  ErrorMsg: String;
  TheDate,TheTime: string;
  TheFile: UTF8String;
  TheFileW: WideString;
  ParamList: TStringList=nil;
  TheHandle: THandle=INVALID_HANDLE_VALUE;
  FT: TFormatSettings;
  TheFileModify: TDateTime;
  lCreationTime, lAccessTime, lModificationTime: FILETIME;
  Arroba: Boolean=false;
  F: TFileStream;
  B: String;
  U: UnicodeString;
begin
  // quick check parameters
  ErrorMsg:=CheckOptions('h', 'help');
  if ErrorMsg<>'' then begin
ShowException(Exception.Create(ErrorMsg));
Terminate;
Exit;
  end;

  // parse parameters
  if HasOption('h', 'help') then begin
WriteHelp;
Terminate;
Exit;
  end;

  if ParamCount=0 then begin
WriteHelp;
Terminate;
Exit;
  end;

  { add your program here }

  TheFile:=ParamStr(1);
  TheDate:=ParamStr(2);
  TheTime:=ParamStr(3);

  if TheFile<>'' then begin
if TheFile[1]='"' then begin
  TheFile:=copy(TheFile,2);
end;
if TheFile[1]='@' then begin
  TheFile:=copy(TheFile,2);
  Arroba:=true;
end;
if TheFile[1]='"' then begin
  TheFile:=copy(TheFile,2);
end;
if TheFile[length(TheFile)]='"' then begin
  TheFile:=copy(TheFile,1,Length(TheFile)-1);
end;

if Arroba then begin
  if not FileExists(TheFile) then begin
writeln('File "',TheFile,'" does not exists.');
Terminate(1);
exit;
  end;

  //Each line is a parameter
  //so

  //Junction Name
  //2020-01-01
  //19:23:00

  ParamList:=TStringList.Create;
  try
F:=TFileStream.Create(TheFile,fmOpenRead or fmShareDenyNone);
SetLength(B,F.Size);
F.Read(B[1],F.Size);
FreeAndNil(F);
ParamList.Text:=B;
TheFile:=Utf8String(Utf8decode(ParamList[0]));
TheDate:=ParamList[1];
TheTime:=ParamList[2];
  finally
FreeAndNil(ParamList);
  end;
end;
  end;


  FT:=DefaultFormatSettings;

  FT.DateSeparator:='-';
  FT.LongDateFormat:='-MM-DD';
  FT.ShortDateFormat:='-MM-DD HH:mm:SS';

  TheFileModify:=StrToDateTime(TheDate+' '+TheTime,FT);

  TheFileW:=WideString(TheFile);

  TheHandle:=CreateFileW(@TheFileW[1], GENERIC_READ or GENERIC_WRITE,
 FILE_SHARE_READ or FILE_SHARE_WRITE,
 Nil, OPEN_EXISTING,
 FILE_FLAG_BACKUP_SEMANTICS or 
FILE_FLAG_OPEN_REPARSE_POINT or FILE_ATTRIBUTE_REPARSE_POINT, 
INVALID_HANDLE_VALUE);
  if TheHandle<>INVALID_HANDLE_VALUE then begin
if GetFileTime(TheHandle,@lCreationTime,@lAccessTime,@lModificationTime) 
then begin
  lModificationTime:=DateTimeToFileTime(TheFileModify);
  if not SetFileTime(TheHandle,lCreationTime,lAccessTime,lModificationTime) 
then begin
writeln('SetFileTime Last Error: ',GetLastError());
CloseHandle(TheHandle);
Terminate(3);
exit;
  end else begin
CloseHandle(TheHandle);
writeln ('Touched "'+TheFile+'" with '+DateTimeToStr(TheFileModify));
Terminate(0);
exit;
  end;
end else begin
  writeln('GetFileTime Last Error: ',GetLastError());
  Terminate(2);
  exit;
end;
  end else begin
writeln('CreateFileW Last Error: ',GetLastError());
Terminate(5);
exit;
  end;

  // stop program loop
  Terminate(0);
end;

constructor TTouchJunction.Create(TheOwner: TComponent);
begin
  inherited Create(TheOwner);
  StopOnException:=True;
end;

destructor TTouchJunction.Destroy;
begin
  inherited Destroy;
end;

procedure TTouchJunction.WriteHelp;
begin
  { 

Re: [fpc-pascal] RTLEventWaitFor

2022-04-05 Thread José Mejuto via fpc-pascal

El 05/04/2022 a las 1:03, Mattias Gaertner via fpc-pascal escribió:

Hi Michael,

Under Linux a RTLEventWaitFor(e,1) usually waits at most 1ms. But under
Windows it usually waits at least 15ms. It seems to round to nearest
1/64 of a second.

Googling this lead me to question the sanity of some bloggers.

Has anyone an idea if this is normal on Windows and if there is an
alternative?

Mattias


Hello,

On Windows the timer resolution is 1/64, that's 15,6 ms. You can change 
it by using "NtSetTimerResolution" but it is system wide and other 
programs can fail or have strange behaviour. MS recommends to not change 
it, but some programs like Chrome do it for some chuncks of time.


You can check the 15.6 ms using a tight loop of GetTickCount.

Have a nice day.

--

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] Reading Serial Hex Data

2020-12-28 Thread José Mejuto via fpc-pascal

El 28/12/2020 a las 2:02, James Richters via fpc-pascal escribió:

I think I figured out why my writeln's are causing an issue.. they are 
introducing a delay between the SerWrite and SerRead...
and the device I am reading is timing out and sending it's response a second 
time.


Hello,

None of the serial devices I have seen do something like that, in fact 
usually they do exactly the opposite, fire and forget, or in other words 
send a message and do not check for errors unless they wait for an 
answer from the host.


Your problem seems to be or a documentation misinterpretation or the 
connection or the device is not using any kind of flow control.



I was under the impression that there was a hardware buffer on the serial 
ports, my packets are very small,
some only a few bytes, but even those are not going into any kind of a hardware 
buffer.


Hardware buffers in serial device is 16 bytes (In fact 14 for receive) 
at most and it is managed by the Windows serial driver to garantee no 
byte is lost. The operation scheme is something like:


1- Serial byte received
2- IRQ signal issued
3- Windows serial driver read serial port and copy byte(s) to driver buffer.
4- Signal IRQ as handled.

The 16 bytes hardware (FIFO) buffer is present to garantee that if steps 
between 2 and 4 takes too much time (this is time scaled in 1990's CPU 
power) no byte is lost. If an Intel 8088 can read 115200bps without any 
byte lost think what a today computer can read.


In order to perform tests there are programs where you create an hex 
string to be sent and inspect the answer from the device. Read 
documentation about how to open the port, specially about the flow 
control sync. XOn/XOff, RTS/CTS. In example some need that you raise the 
RTS line and wait for CTS line to be high before write, if you do not 
wait the device can misinterpret your request and hang or answer 
something stupid, this is automatically done by the Windows serial 
driver if you select the RTS/CTS flow control when open the port.



Have a nice 2021!

--

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] FPC 3.2fixes UTF8Decode strange place

2020-11-02 Thread José Mejuto via fpc-pascal

El 01/11/2020 a las 20:36, AlexeyT via fpc-pascal escribió:

@/José Mejuto, can you pls simplify this place, ie remove "if /IBYTE = 
10" + then/else.


Hello,

I don't have write access, so no, I can not.


--

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


Re: [fpc-pascal] FPC 3.2fixes UTF8Decode strange place

2020-10-28 Thread José Mejuto via fpc-pascal

El 27/10/2020 a las 21:25, AlexeyT via fpc-pascal escribió:

rtl/inc/ustrings.inc

function UTF8ToUnicode(Dest: PUnicodeChar; MaxDestChars: SizeUInt; 
Source: PChar; SourceBytes: SizeUInt): SizeUInt;



a) it has "If (PreChar<>13) and FALSE then" and later some big block. 
with a comment which tells that "and FALSE" is on purpose and block is 
ignored. ?


b) after I removed "that block" I got such trimmed src


Hello,

As the author of that piece of code, UTF8 recommends expanding LF line 
endings to CR+LF but this will generate some troubles and to try to 100% 
conform the spec. the conversion has been added, but disabled so code 
maintainers can easily remove them if needed. If you remove the piece of 
code about #13 you can safely remove the check about #10 which is now 
nonsense so you end with:


---
while (OutputUnicodehttps://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal