i want to download a .jpg but as it is binary it will contain a 0 at some point. so if i use lstrlen to get its length then write it to a file it wont write the whole file and if i use lstrcat it will only append up until a 0. so how do i get the recv'd data into a file???

the only way i can see to do this is too write it to a file with writefile using the return value of recv as the number of bytes to write. but i have to dl .txt's too, but i dont want to write them to a file - just hold them in memory and i was hoping i could just invoke the same routine for both.

thanks for any help.
skud.
Posted on 2001-10-06 10:27:01 by skud
the only way i can see to do this is too write it to a file with writefile using the return value of recv as the number of bytes to write. but i have to dl .txt's too, but i dont want to write them to a file - just hold them in memory and i was hoping i could just invoke the same routine for both.


This isn't possible because of the reason you described already.. Just write all received data to a file, its quite easy.. You can store it in memory as well but you can't have a null terminator then.

Thomas
Posted on 2001-10-06 10:49:44 by Thomas
it is possible :)
maybe i am bad at explaining or you misunderstood.
heres my code:

invoke CreateFile, addr temppicname, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0
mov filehand, eax

xor eax, eax

recv_more:

invoke WriteFile, filehand, addr recvbuff, eax, offset nobytes, 0

invoke recv, sock, addr recvbuff, 1024, 0
cmp eax, 0
jne recv_more

invoke CloseHandle, filehand
invoke closesocket, sock

; --------------------------------------------------------------

this works, but i was hoping i could have the same one for normal text and binary. do .jpg's not have a header? i thought this would result in the header and the picture being in the file, but when i ran the pic it opened in PSP fine. this was the reason i did not use this method in the first place. what i want to do is to download the picture and then view it in my own little viewer. do i have to actually write out the file to do this or can i just keep it in memory? and how do i keep it in memory if it stops at a 0?? i have no experience with anything graphical so to make a .jpg viewer is a big step for me ;)

thanks.
skud.
Posted on 2001-10-06 10:59:41 by skud
Yes, .jpg files do have a header. And having a passing knowledge about it could make your life easier.
Check Wotsit and look for 'jpg'.
Bye!

Latigo
Posted on 2001-10-06 12:45:37 by latigo
skud: I should have made the quote better, I didn't mean it's not possible to do it like you showed in your second post, I meant that it isn't possible to do it the same as with text without any changes..because of the nulls

But your method is perfectly fine.. You can do it in memory as well. Normally the server will give you a 'content-length' header back when you request a resource, allocate the amount of memory indicated by that header, then add everything to that piece of memory instead of to the file.
In some occations (not likely for images, but for scripts etc), this header may be not available, then you should receive data until the connection is closed. Problem here is that you don't know the size before you start downloading... I'd suggest variable (reallocatable) memory for this.
But for images, this is a rare occasion so just stick to content-length.

Thomas
Posted on 2001-10-06 14:50:47 by Thomas
thomas-

ok. could you give an example?
i dunno how to allocate memory and then just add to it etc.

thx.
skud.
Posted on 2001-10-06 19:10:56 by skud
Assuming you can parse the http header and content-length, this is the code:


.data?
contentLength dd ?
pMem dd ?

.code
;assuming contentLength is initialized here

invoke GlobalAlloc, GMEM_FIXED, contentLength
mov pMem, eax
mov edi, eax ; edi is pointer to new mem
xor esi, esi ;esi holds number of bytes already downloaded

recv_more:

; receive max 1024 bytes at a time:
mov eax, contentLength
sub eax, esi
cmp eax, 1024
ja @F
mov eax, 1024
@@:

;receive bytes:
invoke recv, sock, edi, eax, 0

cmp eax, SOCKET_ERROR
je @error

add esi, eax ;update number of bytes downloaded
add edi, eax ;update pointer to next piece

cmp eax, 0
jne recv_more

cmp esi, contentLength
je @done
; if you get here, the server has closed the connection but
; the file wasn't fully downloaded (downloadedBytes != contentLength)
; show error or something


@done:
; file is downloaded, pMem points to file, contentLength holds length
; when you're done with the buffer, deallocate it:
invoke GlobalFree, pMem

@error:
; error handling here (WSAGetLastError)



I've written it without testing but you'll get the idea.

Thomas
Posted on 2001-10-07 03:07:48 by Thomas
thanks thomas.

i opened the .jpg in notepad, that i downloaded, and it has the header in it still but its fine to open with PSP, however it cant preview it in windows expolorer. is this just PSP being tollerant or do i not need to worry about the header??

thanks.
skud.
Posted on 2001-10-08 14:34:08 by skud
What header do you mean exactly? the http header? like this:

HTTP/1.0 200 OK
Content-type: image/jpeg
Content-length: 34902 etc.

JPEG data starts here

You shouldn't leave that header in the file. It won't be a valid jpeg file then.. However I think PSP will be flexible in this and just look for the magic word at the start of a JPG header, and skipping all that precedes it...
If this is your case, just don't add data to the buffer until you've received two CRLFs. If you mean something else, please explain a bit more..

Thomas
Posted on 2001-10-09 11:55:11 by Thomas
yeah, i mean the http header.
it was just out of curiosity really.
that means i have to do it with your method to remove the header.

thanks.
skud.
Posted on 2001-10-09 11:58:11 by skud
I'm not sure if this is what you want... but you can use the 'URLDownloadToFile' function in urlmon.. it does all the 'work' of taking out the headers for you.
Posted on 2001-10-17 10:30:06 by freedumb