Yahoo! search interface: Difference between revisions
Content added Content deleted
(Add task to ARM assembly Raspberry pi) |
(add task to ARM64 assembly Raspberry Pi) |
||
Line 5: | Line 5: | ||
It must implement a '''Next Page''' method, and read URL, Title and Content from results. |
It must implement a '''Next Page''' method, and read URL, Title and Content from results. |
||
<br><br> |
<br><br> |
||
=={{header|AArch64 Assembly}}== |
|||
{{works with|as|Raspberry Pi 3B version Buster 64 bits}} |
|||
<lang AArch64 Assembly> |
|||
/* ARM assembly AARCH64 Raspberry PI 3B */ |
|||
/* program yahoosearch64.s */ |
|||
/* access RosettaCode.org and data extract */ |
|||
/* use openssl for access to port 443 */ |
|||
/* test openssl : package libssl-dev */ |
|||
/*******************************************/ |
|||
/* Constantes file */ |
|||
/*******************************************/ |
|||
/* for this file see task include a file in language AArch64 assembly*/ |
|||
.include "../includeConstantesARM64.inc" |
|||
.equ TAILLEBUFFER, 500 |
|||
.equ SSL_OP_NO_SSLv3, 0x02000000 |
|||
.equ SSL_OP_NO_COMPRESSION, 0x00020000 |
|||
.equ SSL_MODE_AUTO_RETRY, 0x00000004 |
|||
.equ SSL_CTRL_MODE, 33 |
|||
.equ BIO_C_SET_CONNECT, 100 |
|||
.equ BIO_C_DO_STATE_MACHINE, 101 |
|||
.equ BIO_C_SET_SSL, 109 |
|||
.equ BIO_C_GET_SSL, 110 |
|||
.equ LGBUFFERREQ, 512001 |
|||
/*********************************/ |
|||
/* Initialized data */ |
|||
/*********************************/ |
|||
.data |
|||
szMessDebutPgm: .asciz "Début du programme. \n" |
|||
szRetourLigne: .asciz "\n" |
|||
szMessFinOK: .asciz "Fin normale du programme. \n" |
|||
szMessErreur: .asciz "Erreur !!!" |
|||
szMessExtractArea: .asciz "Extraction = " |
|||
szNomSite1: .asciz "search.yahoo.com:443" // host name and port |
|||
szLibStart: .asciz ">Rosetta Code" // search string |
|||
szNomrepCertif: .asciz "/pi/certificats" |
|||
szRequete1: .asciz "GET /search?p=\"Rosettacode.org\"&b=1 HTTP/1.1 \r\nHost: search.yahoo.com\r\nConnection: keep-alive\r\nContent-Type: text/plain\r\n\r\n" |
|||
/*********************************/ |
|||
/* UnInitialized data */ |
|||
/*********************************/ |
|||
.bss |
|||
.align 4 |
|||
sBufferreq: .skip LGBUFFERREQ |
|||
szExtractArea: .skip TAILLEBUFFER |
|||
stNewSSL: .skip 200 |
|||
/*********************************/ |
|||
/* code section */ |
|||
/*********************************/ |
|||
.text |
|||
.global main |
|||
main: |
|||
ldr x0,qAdrszMessDebutPgm |
|||
bl affichageMess // start message |
|||
/* connexion host port 443 and send query */ |
|||
bl envoiRequete |
|||
cmp x0,#-1 |
|||
beq 99f // error ? |
|||
bl analyseReponse |
|||
ldr x0,qAdrszMessFinOK // end message |
|||
bl affichageMess |
|||
mov x0, #0 // return code ok |
|||
b 100f |
|||
99: |
|||
ldr x0,qAdrszMessErreur // error |
|||
bl affichageMess |
|||
mov x0, #1 // return code error |
|||
b 100f |
|||
100: |
|||
mov x8,EXIT // program end |
|||
svc 0 // system call |
|||
qAdrszMessDebutPgm: .quad szMessDebutPgm |
|||
qAdrszMessFinOK: .quad szMessFinOK |
|||
qAdrszMessErreur: .quad szMessErreur |
|||
/*********************************************************/ |
|||
/* connexion host port 443 and send query */ |
|||
/*********************************************************/ |
|||
envoiRequete: |
|||
stp x1,lr,[sp,-16]! // save registers |
|||
stp x2,x3,[sp,-16]! // save registers |
|||
stp x4,x5,[sp,-16]! // save registers |
|||
//************************************* |
|||
// openSsl functions use * |
|||
//************************************* |
|||
//init ssl |
|||
bl OPENSSL_init_crypto |
|||
bl ERR_load_BIO_strings |
|||
mov x2, #0 |
|||
mov x1, #0 |
|||
mov x0, #2 |
|||
bl OPENSSL_init_crypto |
|||
mov x2, #0 |
|||
mov x1, #0 |
|||
mov x0, #0 |
|||
bl OPENSSL_init_ssl |
|||
cmp x0,#0 |
|||
blt erreur |
|||
bl TLS_client_method |
|||
bl SSL_CTX_new |
|||
cmp x0,#0 |
|||
ble erreur |
|||
mov x20,x0 // save contex |
|||
ldr x1,iFlag |
|||
bl SSL_CTX_set_options |
|||
mov x0,x20 // contex |
|||
mov x1,#0 |
|||
ldr x2,qAdrszNomrepCertif |
|||
bl SSL_CTX_load_verify_locations |
|||
cmp x0,#0 |
|||
ble erreur |
|||
mov x0,x20 // contex |
|||
bl BIO_new_ssl_connect |
|||
cmp x0,#0 |
|||
ble erreur |
|||
mov x21,x0 // save bio |
|||
mov x1,#BIO_C_GET_SSL |
|||
mov x2,#0 |
|||
ldr x3,qAdrstNewSSL |
|||
bl BIO_ctrl |
|||
ldr x0,qAdrstNewSSL |
|||
ldr x0,[x0] |
|||
mov x1,#SSL_CTRL_MODE |
|||
mov x2,#SSL_MODE_AUTO_RETRY |
|||
mov x3,#0 |
|||
bl SSL_ctrl |
|||
mov x0,x21 // bio |
|||
mov x1,#BIO_C_SET_CONNECT |
|||
mov x2,#0 |
|||
ldr x3,qAdrszNomSite1 |
|||
bl BIO_ctrl |
|||
mov x0,x21 // bio |
|||
mov x1,#BIO_C_DO_STATE_MACHINE |
|||
mov x2,#0 |
|||
mov x3,#0 |
|||
bl BIO_ctrl |
|||
// compute query length |
|||
mov x2,#0 |
|||
ldr x1,qAdrszRequete1 // query |
|||
1: |
|||
ldrb w0,[x1,x2] |
|||
cmp x0,#0 |
|||
add x8,x2,1 |
|||
csel x2,x8,x2,ne |
|||
bne 1b |
|||
// send query |
|||
mov x0,x21 // bio |
|||
// x1 = address query |
|||
// x2 = length query |
|||
mov x3,#0 |
|||
bl BIO_write // send query |
|||
cmp x0,#0 |
|||
blt erreur |
|||
ldr x22,qAdrsBufferreq // buffer address |
|||
2: // begin loop to read datas |
|||
mov x0,x21 // bio |
|||
mov x1,x22 // buffer address |
|||
ldr x2,qLgBuffer |
|||
mov x3,#0 |
|||
bl BIO_read |
|||
cmp x0,#0 |
|||
ble 4f // error ou pb server |
|||
add x22,x22,x0 |
|||
sub x2,x22,#8 |
|||
ldr x2,[x2] |
|||
ldr x3,qCharEnd |
|||
cmp x2,x3 // text end ? |
|||
beq 4f |
|||
mov x1,#0xFFFFFF // delay loop |
|||
3: |
|||
subs x1,x1,1 |
|||
bgt 3b |
|||
b 2b // loop read other chunk |
|||
4: // read end |
|||
//ldr x0,qAdrsBufferreq // to display buffer response of the query |
|||
//bl affichageMess |
|||
mov x0, x21 // close bio |
|||
bl BIO_free_all |
|||
mov x0,#0 |
|||
b 100f |
|||
erreur: // error display |
|||
ldr x1,qAdrszMessErreur |
|||
bl afficheErreur |
|||
mov x0,#-1 // error code |
|||
b 100f |
|||
100: |
|||
ldp x4,x5,[sp],16 // restaur 2 registers |
|||
ldp x2,x3,[sp],16 // restaur 2 registers |
|||
ldp x1,lr,[sp],16 // restaur 2 registers |
|||
ret // return to address lr x30 |
|||
qAdrszRequete1: .quad szRequete1 |
|||
qAdrsBufferreq: .quad sBufferreq |
|||
iFlag: .quad SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION |
|||
qAdrstNewSSL: .quad stNewSSL |
|||
qAdrszNomSite1: .quad szNomSite1 |
|||
qAdrszNomrepCertif: .quad szNomrepCertif |
|||
qCharEnd: .quad 0x0A0D0A0D300A0D0A |
|||
qLgBuffer: .quad LGBUFFERREQ - 1 |
|||
/*********************************************************/ |
|||
/* response analyze */ |
|||
/*********************************************************/ |
|||
analyseReponse: |
|||
stp x1,lr,[sp,-16]! // save registers |
|||
stp x2,x3,[sp,-16]! // save registers |
|||
ldr x0,qAdrsBufferreq // buffer address |
|||
ldr x1,qAdrszLibStart // key text address |
|||
mov x2,#2 // occurence key text |
|||
mov x3,#-11 // offset |
|||
ldr x4,qAdrszExtractArea // address result area |
|||
bl extChaine |
|||
cmp x0,#-1 |
|||
beq 99f |
|||
ldr x0,qAdrszMessExtractArea |
|||
bl affichageMess |
|||
ldr x0,qAdrszExtractArea // résult display |
|||
bl affichageMess |
|||
ldr x0,qAdrszRetourLigne |
|||
bl affichageMess |
|||
b 100f |
|||
99: |
|||
ldr x0,qAdrszMessErreur // error |
|||
bl affichageMess |
|||
mov x0, #-1 // error return code |
|||
b 100f |
|||
100: |
|||
ldp x2,x3,[sp],16 // restaur 2 registers |
|||
ldp x1,lr,[sp],16 // restaur 2 registers |
|||
ret // return to address lr x30 |
|||
qAdrszLibStart: .quad szLibStart |
|||
qAdrszExtractArea: .quad szExtractArea |
|||
qAdrszMessExtractArea: .quad szMessExtractArea |
|||
qAdrszRetourLigne: .quad szRetourLigne |
|||
/*********************************************************/ |
|||
/* Text Extraction behind text key */ |
|||
/*********************************************************/ |
|||
/* x0 buffer address */ |
|||
/* x1 key text to search */ |
|||
/* x2 number occurences to key text */ |
|||
/* x3 offset */ |
|||
/* x4 result address */ |
|||
extChaine: |
|||
stp x1,lr,[sp,-16]! // save registers |
|||
stp x2,x3,[sp,-16]! // save registers |
|||
stp x4,x5,[sp,-16]! // save registers |
|||
stp x6,x7,[sp,-16]! // save registers |
|||
mov x5,x0 // save buffer address |
|||
mov x6,x1 // save key text |
|||
// compute text length |
|||
mov x8,#0 |
|||
1: // loop |
|||
ldrb w0,[x5,x8] // load a byte |
|||
cmp x0,#0 // end ? |
|||
add x9,x8,1 |
|||
csel x8,x9,x8,ne |
|||
bne 1b // no -> loop |
|||
add x8,x8,x5 // compute text end |
|||
mov x7,#0 |
|||
2: // compute length text key |
|||
ldrb w0,[x6,x7] |
|||
cmp x0,#0 |
|||
add x9,x7,1 |
|||
csel x7,x9,x7,ne |
|||
bne 2b |
|||
3: // loop to search niéme(x2) key text |
|||
mov x0,x5 |
|||
mov x1,x6 |
|||
bl rechercheSousChaine |
|||
cmp x0,#0 |
|||
blt 100f |
|||
subs x2,x2,1 |
|||
ble 31f |
|||
add x5,x5,x0 |
|||
add x5,x5,x7 |
|||
b 3b |
|||
31: |
|||
add x0,x0,x5 // add address text to index |
|||
add x3,x3,x0 // add offset |
|||
sub x3,x3,1 |
|||
// and add length key text |
|||
add x3,x3,x7 |
|||
cmp x3,x8 // > at text end |
|||
bge 98f |
|||
mov x0,0 |
|||
4: // character loop copy |
|||
ldrb w2,[x3,x0] |
|||
strb w2,[x4,x0] |
|||
cbz x2,99f // text end ? return zero |
|||
cmp x0,48 // extraction length |
|||
beq 5f |
|||
add x0,x0,1 |
|||
b 4b // and loop |
|||
5: |
|||
mov x2,0 // store final zéro |
|||
strb w2,[x4,x0] |
|||
add x0,x0,1 |
|||
add x0,x0,x3 // x0 return the last position of extraction |
|||
// it is possible o search another text |
|||
b 100f |
|||
98: |
|||
mov x0,-1 // error |
|||
b 100f |
|||
99: |
|||
mov x0,0 |
|||
100: |
|||
ldp x6,x7,[sp],16 // restaur 2 registers |
|||
ldp x4,x5,[sp],16 // restaur 2 registers |
|||
ldp x2,x3,[sp],16 // restaur 2 registers |
|||
ldp x1,lr,[sp],16 // restaur 2 registers |
|||
ret // return to address lr x30 |
|||
/******************************************************************/ |
|||
/* search substring in string */ |
|||
/******************************************************************/ |
|||
/* x0 contains address string */ |
|||
/* x1 contains address substring */ |
|||
/* x0 return start index substring or -1 if not find */ |
|||
rechercheSousChaine: |
|||
stp x1,lr,[sp,-16]! // save registers |
|||
stp x2,x3,[sp,-16]! // save registers |
|||
stp x4,x5,[sp,-16]! // save registers |
|||
stp x6,x7,[sp,-16]! // save registers |
|||
mov x2,#0 // index position string |
|||
mov x3,#0 // index position substring |
|||
mov x6,#-1 // search index |
|||
ldrb w4,[x1,x3] // load first byte substring |
|||
cbz x4,99f // zero final ? error |
|||
1: |
|||
ldrb w5,[x0,x2] // load string byte |
|||
cbz x5,99f // zero final ? yes -> not found |
|||
cmp x5,x4 // compare character two strings |
|||
beq 2f |
|||
mov x6,-1 // not equal - > raz index |
|||
mov x3,0 // and raz byte counter |
|||
ldrb w4,[x1,x3] // and load byte |
|||
add x2,x2,1 // and increment byte counter |
|||
b 1b // and loop |
|||
2: // characters equal |
|||
cmp x6,-1 // first character equal ? |
|||
csel x6,x2,x6,eq // yes -> start index in x6 |
|||
add x3,x3,1 // increment substring counter |
|||
ldrb w4,[x1,x3] // and load next byte |
|||
cbz x4,3f // zero final ? yes -> search end |
|||
add x2,x2,1 // else increment string index |
|||
b 1b // and loop |
|||
3: |
|||
mov x0,x6 // return start index substring in the string |
|||
b 100f |
|||
99: |
|||
mov x0,-1 // not found |
|||
100: |
|||
ldp x6,x7,[sp],16 // restaur 2 registers |
|||
ldp x4,x5,[sp],16 // restaur 2 registers |
|||
ldp x2,x3,[sp],16 // restaur 2 registers |
|||
ldp x1,lr,[sp],16 // restaur 2 registers |
|||
ret // return to address lr x30 |
|||
/********************************************************/ |
|||
/* File Include fonctions */ |
|||
/********************************************************/ |
|||
/* for this file see task include a file in language AArch64 assembly */ |
|||
.include "../includeARM64.inc" |
|||
</lang> |
|||
{{Output}} |
|||
<pre> |
|||
Début du programme. |
|||
Extraction = Rosetta Code is a programming chrestomathy site. |
|||
Fin normale du programme. |
|||
</pre> |
|||
=={{header|ARM Assembly}}== |
=={{header|ARM Assembly}}== |
||
{{works with|as|Raspberry Pi}} |
{{works with|as|Raspberry Pi}} |