int32 BNetEndpoint::Receive(BNetBuffer& buffer, size_t length, int flags) { BNetBuffer chunk(length); ssize_t bytesReceived = Receive(chunk.Data(), length, flags); if (bytesReceived > 0) buffer.AppendData(chunk.Data(), bytesReceived); return bytesReceived; }
int32 DownloadLoop(void *pDummy) { char *pDetails, *pFile, *pIP, *pPort, *pUser , *pTemp, *pLength, *pLeaf, *pFilenameEnd; uint32 iIPAddress, iFileLength, iDataLength; int32 iPort, iBytesReceived; status_t stReturnCode; BNetEndpoint bneSong; BNetAddress bnaSong; BNetBuffer bnbSong; BFile *bfSong; Preferences *myPrefs; DownloadView *dlView; DownloadWindow *myDownloadWindow; myPrefs = (Preferences *)pDummy; pDetails = myPrefs->pDownloadDetails; pUser = pDetails; pTemp = strchr(pDetails, ' '); *pTemp = '\0'; pTemp++; pIP = pTemp; pTemp = strchr(pTemp, ' '); *pTemp = '\0'; iIPAddress = strtoul(pIP, NULL, 10); pTemp++; pPort = pTemp; pTemp = strchr(pTemp, ' '); *pTemp = '\0'; iPort = atol(pPort); pTemp++; pTemp = strchr(pTemp, '"'); pFile = pTemp; pTemp++; pTemp = strchr(pTemp, '"') + 1; *pTemp = '\0'; pFilenameEnd = pTemp - 1; bnbSong.AppendData(myPrefs->GetUser(), strlen(myPrefs->GetUser())); bnbSong.AppendData(" ", 1); bnbSong.AppendData(pFile, strlen(pFile)); bnbSong.AppendData(" ", 1); bnbSong.AppendData("0", 1); for(pLeaf = pTemp; *pLeaf != '\\' && *pLeaf != '/'; pLeaf-- ); pLeaf++; *pFilenameEnd = '\0'; BPath Path(myPrefs->GetDownloadPath(), NULL, true); if(Path.InitCheck() == B_OK) { // Making sure we have a valid path. Path.Append(pLeaf); bfSong = new BFile(Path.Path(), B_WRITE_ONLY|B_CREATE_FILE|B_OPEN_AT_END); } else // No valid path, use default (current directory) bfSong = new BFile(pLeaf, B_WRITE_ONLY|B_CREATE_FILE|B_OPEN_AT_END); if(bfSong->InitCheck() == B_OK) { stReturnCode = bnaSong.SetTo(iIPAddress, iPort); stReturnCode = bneSong.Connect(bnaSong); // now we need to recieve the mysterious '1'; char *pReceiveBuffer = (char *)malloc(4096); iBytesReceived = bneSong.Receive(pReceiveBuffer, 1); if(iBytesReceived == 1) { pLength = (char *)malloc(50); // more than enough to hold a big number :) printf("sending get command\n"); bneSong.Send("GET",3); pTemp = (char *)bnbSong.Data(); bneSong.Send(pTemp, strlen(pTemp)); pTemp = pLength - 1; // the other client now sends a length followed by the mp3 // according to the unoffical protocol you can not tell how long // the length is. but the mp3 starts // with 0xFF while(isdigit((unsigned char)*pReceiveBuffer) != 0) { pTemp++; iBytesReceived = bneSong.Receive(pReceiveBuffer, 1); *pTemp = *pReceiveBuffer; } *pTemp = '\0'; iFileLength = strtoul(pLength, NULL, 10); //create the download window now we know all the details myDownloadWindow = new DownloadWindow(BRect(100,100, 400, 200), "BeNapster Download", B_DOCUMENT_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, B_NOT_RESIZABLE, B_CURRENT_WORKSPACE); myDownloadWindow->Show(); myDownloadWindow->Lock(); dlView = myDownloadWindow->AddTransfer(pFile, iFileLength); myDownloadWindow->Unlock(); // The 0xFF is part of the mp3 so we need to write it out bfSong->Write(pReceiveBuffer, iBytesReceived); iDataLength = iBytesReceived; myDownloadWindow->Lock(); dlView->AddBytesReceived(iBytesReceived); myDownloadWindow->Unlock(); iBytesReceived = bneSong.Receive(pReceiveBuffer, 4096); bfSong->Write(pReceiveBuffer, iBytesReceived); iDataLength += iBytesReceived; myDownloadWindow->Lock(); dlView->AddBytesReceived(iBytesReceived); myDownloadWindow->Unlock(); while(iDataLength != iFileLength) { iBytesReceived = bneSong.Receive(pReceiveBuffer, 4096); if (iBytesReceived < 0) { break; } bfSong->Write(pReceiveBuffer, iBytesReceived); iDataLength += iBytesReceived; myDownloadWindow->Lock(); dlView->AddBytesReceived(iBytesReceived); myDownloadWindow->Unlock(); } bfSong->Unset(); delete (bfSong); myDownloadWindow->PostMessage(B_QUIT_REQUESTED); } } return(0); }