Discussions related to Visual Prolog
kingchris
Active Member
Posts: 28
Joined: 26 Sep 2005 9:35

Replace nulls in ::string

Unread post by kingchris »

I am writing a system volume crawler.
One of the Win32 functions is

Code: Select all

Vols = string::create(256), Count =  fileSystem_native::getLogicalDriveStrings(256, Vols),
The 256 buffer space is overkill for now I know.

The result is not a string but a series of strings separated by a null then the whole string is terminated by null null.
c:\<null>d:\<null><null>

After two days on and off looking at various ways to parse this data. result in only the C:\null being seen.
So my question is: how to replace all single nulls in this PDC Prolog wide string with say ";". The normal string::replace does not like the nulls.

Then I can parse the string using ";" as the seperator
Martin Meyer
VIP Member
Posts: 328
Joined: 14 Nov 2002 0:01

Re: Replace nulls in ::string

Unread post by Martin Meyer »

Maybe there is a problem in memory::getString/2->. Because when I replaced it by my own version, it has worked out:

Code: Select all

    open core   class predicates     getLogicalDriveStrings : (charCount BufLen, unsigned Result [out]) -> string_list Str_list. clauses     getLogicalDriveStrings(BufLen, Result) = getLogicalDriveStrings1(uncheckedConvert(pointer, Buf)) :-         Buf = memory::allocStringBuffer(BufLen, memory::contextType_string),         Result = fileSystem_native::getLogicalDriveStrings(convert(unsigned, BufLen), Buf).   class predicates     getLogicalDriveStrings1 : (pointer PStr) -> string_list Str_list. clauses     getLogicalDriveStrings1(PStr) = if Str = "" then [] else [Str | getLogicalDriveStrings1(After)] end if :-         %Str = memory::getString(PStr, After).         Str = getString(PStr, After).   class predicates     getString : (pointer Ptr, pointer After [out]) -> string Str. clauses     getString(Ptr, After) = getString1(Ptr, OutStream, After) :-         OutStream = outputStream_string::new().   class predicates     getString1 : (pointer Ptr, outputStream_string OutStream, pointer After [out]) -> string Str. clauses     getString1(Ptr, OutStream, After) = Str :-         Char = memory::getChar(Ptr, AfterChar),         if Char = '\u0000' then             After = AfterChar,             Str = OutStream:getString()         else             OutStream:write(Char),             Str = getString1(AfterChar, OutStream, After)         end if.   clauses     run() :-         StrList = getLogicalDriveStrings(256),         stdIO::write(StrList).
Regards Martin
kingchris
Active Member
Posts: 28
Joined: 26 Sep 2005 9:35

Re: Replace nulls in ::string

Unread post by kingchris »

Thank you Martin Meyer. I will use it.

I had a lot of trouble converting the string to binary via direct functions or binary_outputstreams, as any conversion from strings would not read after the first null, but seeing how your method works will assist in the old learning curve.

Again. Much appreciated.
User avatar
Thomas Linder Puls
VIP Member
Posts: 1398
Joined: 28 Feb 2000 0:01

Re: Replace nulls in ::string

Unread post by Thomas Linder Puls »

The result you show looks like the thing we have called a msStringSeq (Microsoft String Sequence).

There are predicates in the windowsApi class for converting to and from such "sequences":

Code: Select all

domains     msStringSeq = pointer.     % @short A sequence of null (two bytes) terminated Unicode strings.     % The sequence is ended by an empty string (same as two consecutive nulls = 4 x null).     % @end   predicates     toMsStringSeq : (string* StringList) -> msStringSeq Sequence.     fromMsStringSeq : (msStringSeq Sequence) -> string* StringList.     % @short Conversion between string #Sequence and list of string #StringList.     % @end
Regards Thomas Linder Puls
PDC
Martin Meyer
VIP Member
Posts: 328
Joined: 14 Nov 2002 0:01

Re: Replace nulls in ::string

Unread post by Martin Meyer »

ah, thank you Thomas! So, we should do it like

Code: Select all

class predicates     getLogicalDriveStrings : (charCount BufLen, unsigned Result [out]) -> string_list Str_list. clauses     getLogicalDriveStrings(BufLen, Result) = windowsAPI::fromMsStringSeq(uncheckedConvert(windowsAPI::msStringSeq, Buf)) :-         Buf = memory::allocStringBuffer(BufLen, memory::contextType_string),         Result = fileSystem_native::getLogicalDriveStrings(convert(unsigned, BufLen), Buf).
Have I used (the outcommented) memory::getString/2-> wrong before or does it actually have a problem?
Regards Martin
Martin Meyer
VIP Member
Posts: 328
Joined: 14 Nov 2002 0:01

Re: Replace nulls in ::string

Unread post by Martin Meyer »

@Chris: For the learning curve check the implementation of fromMsStringSeq/1-> in windowsAPI.pro, it is done there more efficient than in my code.
Regards Martin
kingchris
Active Member
Posts: 28
Joined: 26 Sep 2005 9:35

Re: Replace nulls in ::string

Unread post by kingchris »

Will do
Post Reply