[Top][All Lists]
[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: Re[1] hexstring help,
Henk Vandecasteele <=