users-prolog
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Re[1] hexstring help


From: Henk Vandecasteele
Subject: Re: Re[1] hexstring help
Date: Fri, 01 Feb 2002 10:23:11 +0100
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.4) Gecko/20011126 Netscape6/6.2.1

This is how I would try to solve it:

- first open a stream, that reads from that the string of hexcodes. Most
  prolog-systems provide this, I don't know about GNU-Prolog. A way
  around is to write the string to file and then open it for reading
  (as I did below).
- next read two characters at the time and translate them, and next
  unify them against the next element in the list.


This avoids translating the whole list to character-codes in advance.
Saving space, and time when for example the first elements in the list
do not match.

Here my tryout, I'm ashamed to say that I don't know how "iso" the
program is:


hexstring(String, List):-
        tell(tmp),
        write(String),
        told,
        see(tmp),
        ( read_and_match(List) ->
           seen
        ;
            /* close the file on failure as well. */
          seen,
          fail
        ).


read_and_match([]):-
        at_end_of_stream.
read_and_match(List):-
        \+ at_end_of_stream,
        List = [Byte|List1],
        get_char(C1),
        get_char(C2),
        match(C1, C2, Byte),
        read_and_match(List1).

get_char(C):-
        get0(Code),
        atom_codes(C, [Code]).


match( C1, C2, Byte):-
        match(C1, N1),
        match(C2, N2),
        Byte is N1 * 16+ N2.



match('0', 0).
match('1', 1).
match('2', 2).
match('3', 3).
match('4', 4).
match('5', 5).
match('6', 6).
match('7', 7).
match('8', 8).
match('9', 9).
match('A', 10).
match('B', 11).
match('C', 12).
match('D', 13).
match('E', 14).
match('F', 15).

/*

using:

?- [hex].
Yes
?-  hexstring('A0000000300002FFFFFFFF8900010001', L).
L = [160,0,0,0,48,0,2,255,255,255,255,137,0,1,0,1]
Yes
?- hexstring('A0000000300002FFFFFFFF8900010001', [160,0,0,0,48,0,2,255,255,255,255,137,0,1,0,1]).
Yes
?- hexstring('A0000000300002FFFFFFFF8900010001', [160,0,0,0,48,0,2,255,255,255,255,137,0,1,0,0]).
 No more !

?-

*/

Gregory Bourassa wrote:

Hi Mariana,

Well, the basic scheme I outined should run pretty efficiently in Prolog. If you plan to process very large strings -- many kilobytes from files, for example -- then you should probably implement the whole thing in C. If it is only dozens of bytes, or even hundreds, I would keep it in Prolog.

Regards.

Gregory
On Jan 31, Renaud Mariana <address@hidden> wrote:

Gregory,



my question is how to unify any hexstring with a list of

bytes efficiently and without too much allocation ?



ex:

hexstring('A0000000300002FFFFFFFF8900010001',

[160,0,0,0,48,0,2,255,255,255,255,137,0,1,0,1]).

returns true.



Regards

Renaud.




-------Message d'origine-------

De : Gregory Bourassa <address@hidden>

Date : 30/01/2002 20:17:50

Mariana,

First, note that I am not familiar with 010A as a hex

representation of [1,10]. Do you

intend to represent things like FFFF as [255,255]?

That said, your conversions should be possible within

Prolog quite easily.


What would be wrong with treating the atom as a character

list until the last moment,

then converting it back to an atom (see

read_term_from_chars and it's writing dual).

Then, if you have a list of chars from the atom and a list

of hex chars, the unification


becomes trivial. A conceptual example:

hexstring([`0,`1,`0,`A], [1,10]) :-

hex_pair( [`0,`1], [1] ),

hex_pair( [`0,`A], [10] ).

where hex_pair is defined as:

hex_pair( [`0,`0], [0] ).

hex_pair( [`0,`1], [1] ).

...etc.

The latter is where my lack of understanding of your

notation becomes an issue. If you

really plan to go up to 255, then hex_pair needs to be

defined in terms of rule that

converts each member of the pair to an integer, multiplies

the left one by 16 and adds

the right one to it.

Regards,

Gregory Bourassa

On Jan 30, Renaud Mariana wrote:

Hi all,

does anybody has a predicate that unifies a list of bytes to

a hexstring (atom) efficiently ?

ex: hexstring('010A', [1,10]). returns true.

the one I propose with the C interface is not elegant,

requires a lot of allocations and also may crash if the list

is too long .

Thanks.

Renaud Mariana

//-------------------------------------------------------

// fill buf with byte-elements of list

// buf must be allocated

int

getCharsFromList(PlTerm list, unsigned char* buf)

{

        PlTerm* pterm = (PlTerm*)list;

        int n = 0;

for(; pterm != (PlTerm*)NIL_WORD; pterm =
(PlTerm*)pterm[1])

                {

pterm = Rd_List( (PlTerm)pterm); if(pterm == 0) break;
                        buf[n++] = Rd_Byte( pterm[0])&0xff;

        }

        return n;

}

// test

// hexstring('A0000000300002FFFFFFFF8900010001', L ).

// hexstring( T,

[160,0,0,0,48,0,2,255,255,255,255,137,0,1,0,1]).

// conversion: atom list of bytes
Bool

hexstring (PlTerm atom, PlTerm list)

{

        int i = 0, t, length;

        char *hexDigits = "0123456789ABCDEF";

        unsigned char buf[1024];

        char str[2048], *str2;

        PlTerm term[1024];

        if(Blt_Non_Var(list)) {

                length = getCharsFromList(list, buf);

                str2 = str;

for ( i = 0; i
                        t = buf[i++];

                        *str2++ = hexDigits[(t >> 4) & 0x0F];

                        *str2++ = hexDigits[ t & 0x0F];

                }

*str2 = 0;
                return Un_String_Check(str, atom);

        }

if( Blt_Var(atom))
                Pl_Err_Instantiation();

        

        str2 = Rd_String_Check(atom);

        length = strlen(str2);

        if ((length ) == 1) {

sscanf(str2++, "df9f66ac", &t);
                term[i++] = Mk_Byte(t);

        }

for ( ; *str2 ; str2+=2 ) { sscanf(str2, "8046584", &t);
                term[i++] = Mk_Byte(t);

        }

return Un_Proper_List_Check(i, term, list);

}

//-------------------------------------------------------

______________________________________________________

Boîte aux lettres - Caramail - http://www.caramail.com

______________________________________________________

Boîte aux lettres - Caramail - http://www.caramail.com








_______________________________________________
Users-prolog mailing list
address@hidden
http://mail.gnu.org/mailman/listinfo/users-prolog






reply via email to

[Prev in Thread] Current Thread [Next in Thread]