Re: [fpc-pascal] Parse unicode scalar
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
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
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
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
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
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