Advertisement
Guest User

PlayerSQBOX.cpp

a guest
Jan 22nd, 2012
318
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 29.84 KB | None | 0 0
  1. /*
  2.   Copyright (C) 2012 ichbtm
  3.  
  4.   This program is free software; you can redistribute it and/or
  5.   modify it under the terms of the GNU General Public License
  6.   as published by the Free Software Foundation; either version 2
  7.   of the License, or (at your option) any later version.
  8.  
  9.   This program is distributed in the hope that it will be useful,
  10.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.   GNU General Public License for more details.
  13.  
  14.   You should have received a copy of the GNU General Public License
  15.   along with this program; if not, write to the Free Software
  16.   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  17. */
  18.  
  19. #ifndef WIN32_LEAN_AND_MEAN
  20. #define WIN32_LEAN_AND_MEAN
  21. #endif
  22.  
  23. #include <windows.h>
  24. #include <winsock2.h>
  25. #include <ws2tcpip.h>
  26. #include "StdAfx.h"
  27. #pragma comment (lib, "Ws2_32.lib")
  28.  
  29. #define SIZE_MTU        1400
  30. #define SIZE_BUF64      8192
  31.  
  32. class IOTCPSocket
  33. {
  34. public:
  35.     IOTCPSocket(std::wstring swUserAgent, std::wstring swUrl);
  36.     virtual ~IOTCPSocket();
  37.     int RunOnce();     
  38.     static void *RunLoop(void *pThis);
  39.     bool StartThread(bool bRestart=true);
  40.     bool StopThread(const bool bAutoTerminate=false);
  41.     int SendCommand(std::wstring swCommand);
  42.  
  43.     bool m_bAvail;
  44.     CRITICAL_SECTION m_CriticalSection;
  45.  
  46. protected:
  47.     int TCPIO_Init(void);
  48.     SOCKADDR_IN* TCPIO_CreateSOCKADDR(const char *sTarget);
  49.     int TCPIO_Connect();
  50.     int TCPIO_Close();
  51.     int TCPIO_Cleanup(void);
  52.     int TCPIO_Send(const BYTE *pData, unsigned int nDataLen);
  53.     int TCPIO_Recv(BYTE **pInData, unsigned int *pnInDataLen);
  54.     int TCPIO_WSelect();
  55.     int TCPIO_RSelect();
  56.  
  57.     int SendBuffer(BYTE *pBuffer, unsigned int nBufLen);
  58.     int RecvString(char ** pBuffer, unsigned int *nBufLen);
  59.     BYTE *AllocatePacket(BYTE *pBuffer, unsigned int size, unsigned int *nPktLen);
  60.  
  61.     virtual int SendOutput() {return 0;};
  62.     virtual int GetInput();
  63.     virtual void ParseCommand(std::wstring swCommand, char** pBuffer, unsigned int* nBufLen) {};
  64.     virtual int ParseAnswer(char* pBuffer, int nBufLen) {return 0;};
  65.     virtual void IfDisconnected(void);
  66.  
  67.     SOCKADDR_IN* m_saddr;
  68.     SOCKET m_s;
  69.  
  70.     std::wstring m_url;
  71.     DWORD m_LastConnectTime;
  72.     bool m_bDisconnected;
  73.     bool m_bCommandToSend;
  74.     std::wstring m_hostname;
  75.     std::wstring m_useragent;
  76.     std::wstring m_verb;
  77.     std::wstring m_hdrs;
  78.     bool m_stream;
  79.  
  80.     HANDLE m_hThread;
  81.     DWORD m_nThreadID;
  82.  
  83.  
  84.     bool m_bRunning;
  85.     bool m_bRestart;
  86. };
  87.  
  88. #include <shellapi.h>
  89. #include <sstream>
  90. #include "PlayerSQBOX.h"
  91.  
  92.  
  93. const int WMSQB_EXIT = 0x0401;
  94.  
  95. std::wstring stows(LPCSTR str, int codepage=CP_ACP);
  96. std::string wstos(LPCWSTR str, int codepage=CP_ACP);
  97. std::wstring utf8tows(LPCSTR str);
  98. std::string wstoutf8(LPCWSTR str);
  99. std::string stoutf8(LPCSTR str, int codepage=CP_ACP);
  100.  
  101. class IO_jsonCommand : public IOTCPSocket {
  102. public:
  103.     IO_jsonCommand(std::wstring swUserAgent, std::wstring swUrl);
  104.     virtual ~IO_jsonCommand();
  105.  
  106.     int SendOutput();
  107.     void ParseCommand(std::wstring swCommand, char** pBuffer, unsigned int* nBufLen);
  108.     int ParseAnswer(char* pBuffer, int nBufLen);
  109.     void IfDisconnected(void);
  110.     int CreateCommand(std::wstring swCommand);
  111.  
  112.     std::wstring m_client;
  113.     std::wstring m_command;
  114. };
  115.  
  116. class IO_GETCover : public IOTCPSocket {
  117. public:
  118.     IO_GETCover(std::wstring swUserAgent, std::wstring swUrl);
  119.     virtual ~IO_GETCover();
  120.  
  121.     int SendOutput();
  122.     void ParseCommand(std::wstring swCommand, char** pBuffer, unsigned int* nBufLen);
  123.     int ParseAnswer(char* pBuffer, int nBufLen);
  124.     void IfDisconnected(void);
  125.     int CreateCommand(std::wstring swCommand);
  126.     std::string BreakDownCommand(std::string instr, std::string command);
  127.  
  128.     std::wstring m_coverpath;
  129.     std::wstring m_command;
  130.     HANDLE m_hFile;
  131.     unsigned int m_filepos;
  132.     unsigned int m_pngsize;
  133. };
  134.  
  135.  
  136. class IO_cometSubscribe : public IOTCPSocket {
  137. public:
  138.     IO_cometSubscribe(std::wstring swUserAgent, std::wstring swAddress);
  139.     virtual ~IO_cometSubscribe();
  140.    
  141.     int SendOutput();
  142.     void ParseCommand(std::wstring swCommand, char** pBuffer, unsigned int* nBufLen);
  143.     int ParseAnswer(char* pBuffer, int nBufLen);
  144.     void IfDisconnected(void);
  145.  
  146.     std::wstring BreakDownCommand(std::wstring instr, std::wstring command);
  147.  
  148.     std::wstring m_client;
  149.     std::wstring m_clientID;
  150.     std::wstring m_songid;
  151.     StateType m_State;
  152.     std::wstring m_Artist;
  153.     std::wstring m_Title;
  154.     std::wstring m_Album;
  155.     std::wstring m_Lyrics;
  156.     std::wstring m_CoverPath;
  157.     std::wstring m_FilePath;
  158.     UINT m_Connected;
  159.     UINT m_Duration;
  160.     UINT m_Position;
  161.     UINT m_Rating;
  162.     UINT m_Volume;
  163.     bool m_Shuffle;
  164.     bool m_Repeat;
  165.     bool m_bHandshakeSent;
  166.     bool m_bConnectionSent;
  167.     bool m_bSubscriptionSent;
  168.     bool m_bNeedHandshake;
  169.     bool m_bNeedConnection;
  170.     bool m_bNeedSubscription;
  171. };
  172.  
  173.  
  174. IO_cometSubscribe*  g_pcometSubscribeHandler;
  175. IO_jsonCommand* g_pCommandHandler;
  176. IO_GETCover*    g_pCoverHandler;
  177.  
  178. CPlayer* CPlayerSQBOX::c_Player = NULL;
  179.  
  180.  
  181. CPlayerSQBOX::CPlayerSQBOX(std::wstring swPlayerPath) : CPlayer(),
  182.     m_Window(),
  183.     m_LastCheckTime(0),
  184.     m_LastPosition(0),
  185.     m_playerPath(swPlayerPath),
  186.     m_server(),
  187.     m_nwebPort(0)
  188. {
  189.     if (m_playerPath==L"") return;
  190.     LSLog(LOG_NOTICE, NULL, L"SQBOX : CplayerSQBOX()");
  191.  
  192.     WCHAR* pbuffer=NULL;
  193.     int len=GetTempPath(0, NULL);
  194.     WCHAR* buffer = new WCHAR[len+1];
  195.     GetTempPath(len, buffer);
  196.     m_CoverPath = buffer;
  197.     m_CoverPath += L"SQBOXCover.png";
  198.     DeleteFile(m_CoverPath.c_str());
  199.  
  200.     size_t pos;
  201.     std::wstring sTemp=m_playerPath;
  202.  
  203.     pos = sTemp.find(L":");
  204.     std::wstring server = sTemp.substr(0,pos);
  205.     sTemp = sTemp.substr(pos+1,std::wstring::npos);
  206.  
  207.     pos = sTemp.find(L" ");
  208.     std::wstring webport = sTemp.substr(0,pos);
  209.     sTemp = sTemp.substr(pos+1,std::wstring::npos);
  210.  
  211.     m_server = server+L":"+webport;
  212.  
  213.     g_pCommandHandler = new IO_jsonCommand(L"Rainmeter SQBOX Nowplaying Pluggin", m_server);
  214.     g_pCommandHandler->m_client = sTemp;
  215.     g_pCommandHandler->StartThread();
  216.  
  217.     g_pCoverHandler = new IO_GETCover(L"Rainmeter SQBOX Nowplaying Pluggin", m_server);
  218.     g_pCoverHandler->m_coverpath = m_CoverPath;
  219.     g_pCoverHandler->StartThread();
  220.  
  221.  
  222.     g_pcometSubscribeHandler = new IO_cometSubscribe(L"Rainmeter SQBOX Nowplaying Pluggin", m_server);
  223.     g_pcometSubscribeHandler->m_client = sTemp;
  224.     g_pcometSubscribeHandler->StartThread();
  225.  
  226.     m_LastCheckTime = GetTickCount();
  227.    
  228.     m_Initialized = true;
  229.  
  230. }
  231.  
  232. CPlayerSQBOX::~CPlayerSQBOX()
  233. {
  234.     m_Initialized = false;
  235.     LSLog(LOG_NOTICE, NULL, L"SQBOX : ~CPlayerSQBOX()");
  236.     c_Player = NULL;
  237.  
  238.     if (g_pcometSubscribeHandler) {
  239.         delete g_pcometSubscribeHandler;
  240.     }
  241.  
  242.  
  243.     if (g_pCommandHandler) {
  244.         delete g_pCommandHandler;
  245.     }
  246.  
  247.     if (g_pCoverHandler) {
  248.         delete g_pCoverHandler;
  249.     }
  250.  
  251. }
  252.  
  253. /*
  254. ** Create
  255. **
  256. ** Creates a shared class object.
  257. **
  258. */
  259. CPlayer* CPlayerSQBOX::Create(std::wstring swPlayerPath)
  260. {
  261.     LSLog(LOG_NOTICE, NULL, L"SQBOX : Create()");
  262.     if (!c_Player)
  263.     {
  264.         c_Player = new CPlayerSQBOX(swPlayerPath);
  265.     }
  266.     return c_Player;
  267. }
  268.  
  269.  
  270. // UpdateData
  271. void CPlayerSQBOX::UpdateData()
  272. {
  273.     EnterCriticalSection(&g_pcometSubscribeHandler->m_CriticalSection);
  274.        
  275.     m_State = (StateType) g_pcometSubscribeHandler->m_State;
  276.            
  277.     if (m_Artist!=g_pcometSubscribeHandler->m_Artist || m_Title!=g_pcometSubscribeHandler->m_Title)
  278.         ++m_TrackCount;
  279.  
  280.     m_Artist = g_pcometSubscribeHandler->m_Artist;
  281.    
  282.     if (m_Album!=g_pcometSubscribeHandler->m_Album) {
  283.  
  284.         g_pCoverHandler->CreateCommand(L"/music/" + g_pcometSubscribeHandler->m_songid + L"/cover_96x96_p.png");
  285.     }
  286.  
  287.     m_Title = g_pcometSubscribeHandler->m_Title;
  288.  
  289.     m_Album = g_pcometSubscribeHandler->m_Album;
  290.    
  291.     m_Duration = g_pcometSubscribeHandler->m_Duration;
  292.    
  293.     if ((m_State == STATE_PLAYING) && (m_LastPosition == g_pcometSubscribeHandler->m_Position)) {
  294.         m_Position = m_LastPosition + (DWORD)(GetTickCount()-m_LastCheckTime)/1000;
  295.     }
  296.     else {
  297.             m_LastPosition = g_pcometSubscribeHandler->m_Position;
  298.             m_Position = m_LastPosition;
  299.             m_LastCheckTime = GetTickCount();
  300.     }
  301.  
  302.    
  303.     m_Rating = g_pcometSubscribeHandler->m_Rating;
  304.    
  305.     m_Volume = g_pcometSubscribeHandler->m_Volume;
  306.    
  307.     m_Shuffle = g_pcometSubscribeHandler->m_Shuffle;
  308.    
  309.     m_Repeat = g_pcometSubscribeHandler->m_Repeat;
  310.  
  311.     LeaveCriticalSection(&g_pcometSubscribeHandler->m_CriticalSection);
  312.  
  313. }
  314.  
  315.  
  316.  
  317. // Play
  318. void CPlayerSQBOX::Play()
  319. {
  320.     g_pCommandHandler->CreateCommand(L"play 1");
  321.  
  322. }
  323.  
  324.  
  325. // Stop
  326. void CPlayerSQBOX::Stop()
  327. {
  328.     g_pCommandHandler->CreateCommand(L"stop 1");
  329. }
  330.  
  331.  
  332. // Pause
  333. void CPlayerSQBOX::Pause()
  334. {
  335.     g_pCommandHandler->CreateCommand(L"pause 1");
  336. }
  337.  
  338.  
  339. // Next
  340. void CPlayerSQBOX::Next()
  341. {
  342.     g_pCommandHandler->CreateCommand(L"button jump_fwd");
  343. }
  344.  
  345.  
  346. // Previous
  347. void CPlayerSQBOX::Previous()
  348. {
  349.     g_pCommandHandler->CreateCommand(L"button jump_rew");
  350. }
  351.  
  352.  
  353. // SetPosition
  354. void CPlayerSQBOX::SetPosition(int position)
  355. {
  356.     wstringstream REQ;
  357.     REQ << L"time ";
  358.     REQ << position;
  359.     g_pCommandHandler->CreateCommand(REQ.str());
  360. }
  361.  
  362.  
  363. // SetRating
  364. void CPlayerSQBOX::SetRating(int rating)
  365. {
  366.  
  367. }
  368.  
  369.  
  370. // SetVolume
  371. void CPlayerSQBOX::SetVolume(int volume)
  372. {
  373.     wstringstream REQ;
  374.     REQ << L"mixer volume ";
  375.     REQ << volume;
  376.     g_pCommandHandler->CreateCommand(REQ.str());
  377. }
  378.  
  379.  
  380. // SetShuffle
  381. void CPlayerSQBOX::SetShuffle(bool state)
  382. {
  383.     wstringstream REQ;
  384.     REQ << L"playlist shuffle ";
  385.     if (state) REQ << 1; else REQ << 0;
  386.     g_pCommandHandler->CreateCommand(REQ.str());
  387. }
  388.  
  389.  
  390. // SetRepeat
  391. void CPlayerSQBOX::SetRepeat(bool state)
  392. {
  393.     wstringstream REQ;
  394.     REQ << L"playlist repeat ";
  395.     if (state) REQ << 1; else REQ << 0;
  396.     g_pCommandHandler->CreateCommand(REQ.str());
  397. }
  398.  
  399.  
  400.  
  401. // ClosePlayer
  402. void CPlayerSQBOX::ClosePlayer()
  403. {
  404.     //pause
  405.     g_pCommandHandler->CreateCommand(L"button power");
  406. }
  407.  
  408.  
  409. // OpenPlayer
  410. void CPlayerSQBOX::OpenPlayer(std::wstring& path)
  411. {
  412.     if (!m_Initialized)
  413.     {
  414.         if (path.empty())
  415.             ShellExecute(NULL, L"open", path.c_str(), NULL, NULL, SW_SHOW);
  416.     }
  417.     else
  418.     {
  419.         // Already active, restore the window
  420.         ShowWindow(m_Window, SW_SHOWNORMAL);
  421.         BringWindowToTop(m_Window);
  422.     }
  423. }
  424.  
  425.  
  426.  
  427.  
  428.  
  429.  
  430.  
  431. IO_jsonCommand::IO_jsonCommand(std:: wstring swUserAgent, std::wstring swUrl) : IOTCPSocket(swUserAgent, swUrl),
  432.     m_client(),
  433.     m_command()
  434. {
  435.     m_verb=L"POST";
  436.     m_hdrs=L"";
  437. }
  438.  
  439. IO_jsonCommand::~IO_jsonCommand(){
  440.  
  441. }
  442.  
  443. void IO_jsonCommand::IfDisconnected(void)
  444. {
  445.     m_command=L"";
  446.     IOTCPSocket::IfDisconnected();
  447. }
  448.  
  449.  
  450. int IO_jsonCommand::CreateCommand(std::wstring sCommand)
  451. {
  452.     int ret = 0;
  453.     if ((m_command==L"")) {
  454.         m_command=sCommand;
  455.         m_bCommandToSend=true;
  456.         ret=1;
  457.     }
  458.     return ret;
  459. }
  460.  
  461. int IO_jsonCommand::SendOutput()
  462. {
  463.     int ret = 0;
  464.  
  465.     if(m_command!=L"") {
  466.         ret = SendCommand(m_command);
  467.         m_command=L"";
  468.     }
  469.     return ret;
  470. }
  471.  
  472. void IO_jsonCommand::ParseCommand(std::wstring swCommand, char** pBuffer, unsigned int* nBufLen)
  473. {
  474.     std::wstringstream REQ;
  475.  
  476.     size_t pos;
  477.     std::wstring swTemp=m_command;
  478.     std::wstring swTemp2;
  479.  
  480.     REQ <<  "{\"id\":1,\"method\":\"slim.request\",\"params\":[\"" << m_client.c_str() << "\",[";
  481.  
  482.     pos = swTemp.find_first_of(L" ");
  483.     if (pos != std::string::npos) {
  484.         swTemp2 = swTemp.substr(0,pos);
  485.         REQ << "\"" << swTemp2.c_str() << "\"";
  486.         swTemp = swTemp.substr(pos+1,std::string::npos);
  487.     }
  488.  
  489.     pos = swTemp.find_first_of(L" ");
  490.     if (pos != std::string::npos) {
  491.         swTemp2 = swTemp.substr(0,pos);
  492.         REQ << ",\"" << swTemp2.c_str() << "\"";
  493.         swTemp = swTemp.substr(pos+1,std::string::npos);
  494.     }
  495.  
  496.     pos = swTemp.find_first_of(L" ");
  497.     if (pos != std::string::npos) {
  498.         swTemp2 = swTemp.substr(0,pos);
  499.         REQ << ",\"" << swTemp2.c_str() << "\"";
  500.     } else {
  501.         REQ << ",\"" << swTemp.c_str() << "\"";
  502.     }
  503.  
  504.  
  505.     REQ << "]]}";
  506.        
  507.     swTemp = REQ.str();
  508.  
  509.     std::wstringstream packet;
  510.     packet << m_verb << L" /jsonrpc.js" << L" HTTP/1.1\r\n";
  511.     packet << L"User-Agent:" << m_useragent << L"\r\n";
  512.     //packet << m_hdrs << L"\r\n";
  513.     packet << L"Content-Length:" << swTemp.length() << L"\r\n";
  514.     packet << L"\r\n";
  515.     packet << swTemp;
  516.     std::wstring swTemp3 = packet.str();
  517.  
  518.     char* str1;
  519.     std::string sTemp = wstos(swTemp3.c_str());
  520.     str1=const_cast<char*>(sTemp.c_str());
  521.     *nBufLen=(unsigned int) swTemp3.length();
  522.     *pBuffer=(char*)new BYTE[*nBufLen];
  523.     std::memcpy(*pBuffer, str1, *nBufLen);
  524. }
  525.  
  526. int IO_jsonCommand::ParseAnswer(char* pBuffer, int nBufLen)
  527. {
  528.     //on remet l'état intitial
  529.     return 0;
  530. }
  531.  
  532.  
  533.  
  534.  
  535.  
  536. IO_GETCover::IO_GETCover(std:: wstring swUserAgent, std::wstring swUrl) : IOTCPSocket(swUserAgent, swUrl),
  537.     m_coverpath(),
  538.     m_command()
  539. {
  540.     m_verb=L"GET";
  541.     m_hdrs=L"";
  542. }
  543.  
  544. IO_GETCover::~IO_GETCover(){
  545.  
  546. }
  547.  
  548. void IO_GETCover::IfDisconnected(void)
  549. {
  550.     m_command=L"";
  551.     IOTCPSocket::IfDisconnected();
  552. }
  553.  
  554.  
  555. int IO_GETCover::CreateCommand(std::wstring sCommand)
  556. {
  557.     m_filepos=0;
  558.     DeleteFile(m_coverpath.c_str());
  559.     m_command=sCommand;
  560.     m_bCommandToSend=true;
  561.     return 1;
  562. }
  563.  
  564. int IO_GETCover::SendOutput()
  565. {
  566.     int ret = 0;
  567.     ret = SendCommand(m_command);
  568.     return ret;
  569. }
  570.  
  571. void IO_GETCover::ParseCommand(std::wstring swCommand, char** pBuffer, unsigned int* nBufLen)
  572. {
  573.     std::wstringstream packet;
  574.     packet << m_verb << L" " << m_command << L" HTTP/1.1\r\n";
  575.     packet << L"User-Agent:" << m_useragent << L"\r\n";
  576.     //packet << m_hdrs << L"\r\n";
  577.     packet << L"Content-Length:0\r\n";
  578.     packet << L"\r\n";
  579.  
  580.     std::wstring swTemp = packet.str();
  581.  
  582.     char* str1;
  583.     std::string sTemp = wstos(swTemp.c_str());
  584.     str1=const_cast<char*>(sTemp.c_str());
  585.     *nBufLen=(unsigned int) swTemp.length();
  586.     *pBuffer=(char*)new BYTE[*nBufLen];
  587.     std::memcpy(*pBuffer, str1, *nBufLen);
  588. }
  589.  
  590. int IO_GETCover::ParseAnswer(char* pBuffer, int nBufLen)
  591. {
  592.     unsigned int top = SIZE_BUF64;
  593.     DWORD dwSize = 0;
  594.     size_t pos=0;
  595.     if (m_filepos==0) {
  596.         m_pngsize=0;
  597.         std::string header = pBuffer;
  598.         pos=header.find("PNG");
  599.         if (pos != std::string::npos) {
  600.             pos-=1;
  601.             pBuffer+=pos;
  602.             nBufLen-=pos;
  603.             m_filepos= pos;
  604.             top -= pos;
  605.             std::string sSize=BreakDownCommand(header, "Content-Length: ");
  606.             m_pngsize=atoi(sSize.c_str());
  607.            
  608.         }
  609.     } else m_filepos+=nBufLen;
  610.  
  611.     m_hFile = CreateFile(m_coverpath.c_str(),                // name of the write
  612.                       FILE_APPEND_DATA,         // open for writing
  613.                       0,                      // do not share
  614.                       NULL,                   // default security
  615.                       OPEN_ALWAYS,             // create new file only
  616.                       FILE_ATTRIBUTE_NORMAL,  // normal file
  617.                       NULL);                  // no attr. template
  618.     if (m_hFile != INVALID_HANDLE_VALUE) {
  619.         WriteFile(
  620.             m_hFile,           // open file handle
  621.             pBuffer,      // start of data to write
  622.             nBufLen,  // number of bytes to write
  623.             &dwSize, // number of bytes that were written
  624.             NULL);            // no overlapped structure
  625.         CloseHandle(m_hFile);
  626.     }
  627.  
  628.     return 0;
  629. }
  630.  
  631. std::string IO_GETCover::BreakDownCommand(std::string instr, std::string command)
  632. {
  633.     std::string outstr;
  634.     size_t pos = instr.find(command);
  635.     if(pos==std::string::npos) return "";
  636.     pos += command.length();
  637.  
  638.     size_t start = pos;
  639.     //seek end of value
  640.     while (pos<instr.length()) {
  641.         if (instr[pos]!=L'\r') pos++;
  642.         else break;
  643.     }
  644.  
  645.     return instr.substr(start,pos-start);
  646. }
  647.  
  648.  
  649.  
  650.  
  651. IO_cometSubscribe::IO_cometSubscribe(std::wstring swUserAgent, std::wstring swUrl) : IOTCPSocket(swUserAgent, swUrl),
  652.     m_client(),
  653.     m_clientID(),
  654.     m_songid(),
  655.     m_State(STATE_STOPPED),
  656.     m_Artist(),
  657.     m_Title(),
  658.     m_Album(),
  659.     m_Lyrics(),
  660.     m_CoverPath(),
  661.     m_FilePath(),
  662.     m_Duration(0),
  663.     m_Position(0),
  664.     m_Rating(0),
  665.     m_Volume(0),
  666.     m_Shuffle(false),
  667.     m_Repeat(false),
  668.     m_bNeedHandshake(true),
  669.     m_bNeedConnection(false),
  670.     m_bNeedSubscription(false),
  671.     m_bHandshakeSent(false),
  672.     m_bSubscriptionSent(false),
  673.     m_bConnectionSent(false),
  674.     m_Connected(false)
  675. {
  676.     m_verb=L"POST";
  677.     m_hdrs=L"Content-Type: text/json";
  678.     m_bCommandToSend=true;
  679. }
  680.  
  681. IO_cometSubscribe::~IO_cometSubscribe(){
  682. }
  683.  
  684. void IO_cometSubscribe::IfDisconnected(void) {
  685.     m_songid=L"";
  686.     m_State=STATE_STOPPED;
  687.     m_Artist=L"";
  688.     m_Title=L"";
  689.     m_Album=L"";
  690.     m_Lyrics=L"";
  691.     m_CoverPath=L"";
  692.     m_FilePath=L"";
  693.     m_Duration=0;
  694.     m_Position=0;
  695.     m_Rating=0;
  696.     m_Volume=0;
  697.     m_Shuffle=false;
  698.     m_Repeat=false;
  699.     m_bNeedHandshake=true;
  700.     m_bNeedConnection=false;
  701.     m_bNeedSubscription=false;
  702.     m_bHandshakeSent=false;
  703.     m_bSubscriptionSent=false;
  704.     m_bConnectionSent=false;
  705.     m_Connected=false;
  706.     IOTCPSocket::IfDisconnected();
  707.     m_bCommandToSend=true;
  708. }
  709.  
  710.  
  711. int IO_cometSubscribe::SendOutput()
  712. {
  713.     int ret = 0;
  714.     if(!m_bHandshakeSent && m_bNeedHandshake) {
  715.         std::wstringstream REQ1;
  716.         REQ1 << "[{\"channel\":\"\\/meta\\/handshake\","
  717.             "\"supportedConnectionTypes\":[\"streaming\"],"
  718.             "\"version\":\"1.0\"}]";
  719.         ret=SendCommand(REQ1.str());
  720.         m_bHandshakeSent=true;
  721.     }
  722.  
  723.     if (!m_bConnectionSent && m_bNeedConnection) {
  724.         std::wstringstream REQ2;
  725.         REQ2 << "[{\"clientId\":\"";
  726.         REQ2 <<  m_clientID;
  727.         REQ2 <<  "\",\"connectionType\":\"streaming\",\"channel\":\"\\/meta\\/connect\"},"
  728.                 "{\"clientId\":\"";
  729.         REQ2 <<  m_clientID;
  730.         REQ2 <<  "\",\"subscription\":\"\\/";
  731.         REQ2 <<  m_clientID;
  732.         REQ2 <<  "\\/**\",\"channel\":\"\\/meta\\/subscribe\"}] ";
  733.  
  734.         ret=SendCommand(REQ2.str());
  735.         m_bConnectionSent=true;
  736.     }
  737.    
  738.     if(!m_bSubscriptionSent && m_bNeedSubscription) {
  739.         std::wstringstream REQ3;
  740.         REQ3 << "[{\"id\":1,\"data\":{\"request\":[\"";
  741.         REQ3 << m_client.c_str();
  742.         REQ3 << "\",[\"status\",\"-\",\"1\",\"subscribe:30\"]],"
  743.                 "\"response\":\"\\/";
  744.         REQ3 << m_clientID;
  745.         REQ3 << "\\/slim\\/status\"},"
  746.                 "\"channel\":\"\\/slim\\/subscribe\"}] ";
  747.         ret = SendCommand(REQ3.str());
  748.         m_bSubscriptionSent=true;
  749.     }
  750.     return ret;
  751. }
  752.  
  753.  
  754.  
  755. void IO_cometSubscribe::ParseCommand(std::wstring swCommand, char** pBuffer, unsigned int* nBufLen)
  756. {
  757.     char* str1;
  758.     std::wstringstream packet;
  759.     packet << m_verb << L" /cometd HTTP/1.1\r\n";
  760.     packet << L"User-Agent:" << m_useragent << L"\r\n";
  761.     packet << m_hdrs << L"\r\n";
  762.     packet << L"Content-Length:" << swCommand.length() << L"\r\n";
  763.     packet << L"\r\n";
  764.     packet << swCommand;
  765.     std::wstring swTemp = packet.str();
  766.     std::string sTemp = wstos(swTemp.c_str());
  767.     str1=const_cast<char*>(sTemp.c_str());
  768.     *nBufLen=(unsigned int) sTemp.length();
  769.     *pBuffer=(char*)new BYTE[*nBufLen];
  770.     memcpy(*pBuffer, str1, *nBufLen);
  771. }
  772.  
  773. int IO_cometSubscribe::ParseAnswer(char* pBuffer, int nBufLen)
  774. {
  775.     if(pBuffer==NULL) return 0;
  776.     std::string sBuffer=(char*)pBuffer;
  777.     std::wstring swAnswer=utf8tows(sBuffer.c_str());
  778.  
  779.     size_t pos = swAnswer.find(L"[{\"data");
  780.     if (pos != std::string::npos) {
  781.         std::wstring swError = BreakDownCommand(swAnswer, L"error");
  782.         if(swError!=L"") {
  783.             return -1;
  784.         }
  785.  
  786.         std::wstring swMode = BreakDownCommand(swAnswer, L"mode");
  787.         if (swMode==L"play") m_State = STATE_PLAYING;
  788.         else if (swMode==L"stop") m_State = STATE_STOPPED;
  789.         else if (swMode==L"pause") m_State = STATE_PAUSED;
  790.         else m_State = STATE_PAUSED;
  791.  
  792.         std::wstring swConnected = BreakDownCommand(swAnswer, L"player_connected");
  793.         if(swConnected!=L"") m_Connected = _wtoi(swConnected.c_str());
  794.         if(m_Connected==0) m_State = STATE_STOPPED;
  795.  
  796.         std::wstring swSongID = BreakDownCommand(swAnswer, L"id");
  797.         if(swSongID!=L"") m_songid = swSongID.c_str();
  798.  
  799.         std::wstring swTime = BreakDownCommand(swAnswer, L"time");
  800.         if(swTime!=L"") m_Position = _wtoi(swTime.c_str());
  801.  
  802.         std::wstring swRate = BreakDownCommand(swAnswer, L"rate");
  803.         if(swRate!=L"") m_Rating = _wtoi(swRate.c_str());
  804.  
  805.         std::wstring swDuration = BreakDownCommand(swAnswer, L"duration");
  806.         if(swDuration!=L"") m_Duration = _wtoi(swDuration.c_str());
  807.  
  808.         std::wstring swVolume = BreakDownCommand(swAnswer, L"mixer volume");
  809.         if(swVolume!=L"") m_Volume = _wtoi(swVolume.c_str());
  810.  
  811.         std::wstring swArtist = BreakDownCommand(swAnswer, L"artist");
  812.         if(swArtist!=L"") m_Artist = swArtist.c_str();
  813.  
  814.         std::wstring swTitle = BreakDownCommand(swAnswer, L"title");
  815.         if(swTitle!=L"") m_Title = swTitle.c_str();
  816.  
  817.         std::wstring swAlbum = BreakDownCommand(swAnswer, L"album");
  818.         if(swAlbum!=L"") m_Album = swAlbum.c_str();
  819.  
  820.         std::wstring swShuffle = BreakDownCommand(swAnswer, L"playlist shuffle");
  821.         if(swShuffle!=L"") m_Shuffle = (bool) _wtoi(swShuffle.c_str());
  822.  
  823.         std::wstring swRepeat = BreakDownCommand(swAnswer, L"playlist repeat");
  824.         if(swRepeat!=L"") m_Repeat = (bool) _wtoi(swRepeat.c_str());
  825.  
  826.     } else if (m_bNeedHandshake) {
  827.         std::wstring swClientID = BreakDownCommand(swAnswer, L"clientId");
  828.         if(swClientID!=L"") {
  829.             m_clientID = swClientID.c_str();
  830.             m_bNeedHandshake=false;
  831.             m_bNeedConnection=true;
  832.             m_bCommandToSend=true;
  833.         } else {
  834.             return -1;
  835.         }
  836.  
  837.     } else if (m_bNeedConnection) {
  838.         std::wstring swSubs = BreakDownCommand(swAnswer, L"successful");
  839.         if(swSubs==L"true") {
  840.             m_bNeedConnection=false;
  841.             m_bNeedSubscription=true;
  842.             m_bCommandToSend=true;
  843.         } else {
  844.             return -1;
  845.         }
  846.     } else if (m_bNeedSubscription) {
  847.         std::wstring swSubs = BreakDownCommand(swAnswer, L"successful");
  848.         if(swSubs==L"true") {
  849.             m_bNeedSubscription=false;
  850.         } else {
  851.             return -1;
  852.         }
  853.  
  854.     }
  855.  
  856.     return 0;
  857. }
  858.  
  859. std::wstring IO_cometSubscribe::BreakDownCommand(std::wstring instr, std::wstring command)
  860. {
  861.     std::wstring outstr;
  862.     size_t pos = instr.find(command);
  863.     if(pos==std::wstring::npos) return L"";
  864.     pos += command.length()+2;
  865.     bool btext=false;
  866.     if (instr[pos]==L'\"') {
  867.         pos+=1;
  868.         btext=true;
  869.     }
  870.  
  871.     size_t start = pos;
  872.     //seek end of value
  873.     while (pos<instr.length()) {
  874.         if (btext) {
  875.             if (instr[pos]!=L'\"') pos++;
  876.             else break;
  877.         }
  878.         if (!btext) {
  879.             if (instr[pos]!=L'}' && instr[pos]!=L'\"' && instr[pos]!=L',') pos++;
  880.             else break;
  881.         }
  882.     }
  883.  
  884.     return instr.substr(start,pos-start);
  885. }
  886.  
  887.  
  888.  
  889.  
  890. IOTCPSocket::IOTCPSocket(std::wstring swUserAgent, std::wstring swUrl):
  891.     m_bCommandToSend(false),
  892.  
  893.     m_bRunning(false),
  894.     m_bRestart(false),
  895.  
  896.     m_url(swUrl),
  897.     m_useragent(swUserAgent),
  898.     m_verb(),
  899.     m_hdrs(),
  900.     m_s(0),
  901.     m_saddr(NULL),
  902.  
  903.     m_bDisconnected(true),
  904.     m_LastConnectTime(NULL)
  905. {
  906.     InitializeCriticalSection(&m_CriticalSection);
  907.     TCPIO_Init();
  908. }
  909.  
  910.  
  911. IOTCPSocket::~IOTCPSocket(){
  912.     StopThread();
  913.     TCPIO_Cleanup();
  914.     WSACleanup();
  915. }
  916.  
  917. void IOTCPSocket::IfDisconnected(void) {
  918.     m_bDisconnected=true;
  919.     m_bCommandToSend=false;
  920.  
  921.     TCPIO_Cleanup();
  922. }
  923.  
  924. //OK
  925. int IOTCPSocket::TCPIO_Cleanup(void)
  926. {
  927.     if (m_s!=NULL) {
  928.         TCPIO_Close();
  929.         m_s=0;
  930.     }
  931.     if (m_saddr) {
  932.         free(m_saddr);
  933.         m_saddr=NULL;
  934.     }
  935.  
  936.     return 0;
  937. }
  938.  
  939. //OK
  940. int IOTCPSocket::TCPIO_Connect()
  941. {
  942.     if ((GetTickCount()-m_LastConnectTime)<30000) return 0;
  943.  
  944.     m_LastConnectTime=GetTickCount();
  945.  
  946.     std::string sTemp = wstos(m_url.c_str());
  947.     m_saddr=TCPIO_CreateSOCKADDR(const_cast<const char*>(sTemp.c_str()));
  948.     if (m_saddr==NULL) {
  949.         return 0;
  950.     }
  951.  
  952.  
  953.     // Create socket
  954.     SOCKET s;
  955.     int res;
  956.     s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
  957.     if(s==INVALID_SOCKET) return NULL;
  958.  
  959.     //setblocking
  960.     u_long argp = 0;
  961.     res = ioctlsocket(s, FIONBIO, &argp);
  962.     if (res==SOCKET_ERROR) {
  963.         int err = WSAGetLastError();
  964.         return NULL;
  965.     }
  966.  
  967.     int on=1;
  968.     res = setsockopt(s,SOL_SOCKET,SO_REUSEADDR, (const char *)&on, sizeof(on));
  969.     if (res==SOCKET_ERROR) {
  970.         int err = WSAGetLastError();
  971.         return NULL;
  972.     }
  973.  
  974.     struct linger l;
  975.     l.l_onoff = 0;
  976.     res=setsockopt(s,SOL_SOCKET,SO_LINGER, (const char *)&l,sizeof(l));
  977.     if (res==SOCKET_ERROR) {
  978.         int err = WSAGetLastError();
  979.         return NULL;
  980.     }
  981.  
  982.     bool ndelay = TRUE;
  983.     res=setsockopt(s,IPPROTO_TCP,TCP_NODELAY,(char *)&ndelay,sizeof(BOOL));
  984.     if (res==SOCKET_ERROR) {
  985.         int err = WSAGetLastError();
  986.         return NULL;
  987.     }
  988.  
  989.     // Connect to remote host
  990.     res=connect(s, (const SOCKADDR*)m_saddr,sizeof(SOCKADDR_IN));
  991.     if (res==SOCKET_ERROR) {
  992.         int err = WSAGetLastError();
  993.         //if (err != WSAEWOULDBLOCK && err != WSAEINPROGRESS) {
  994.             closesocket(s);
  995.             return NULL;
  996.         //}
  997.     }
  998.  
  999.     //setnonblocking
  1000.     u_long argp = 1;
  1001.     res = ioctlsocket(s, FIONBIO, &argp);
  1002.     if (res==SOCKET_ERROR) {
  1003.         int err = WSAGetLastError();
  1004.         return NULL;
  1005.     }
  1006.  
  1007.     m_s=s;
  1008.     return (int)s;
  1009. }
  1010.  
  1011.  
  1012. int IOTCPSocket::TCPIO_Close()
  1013. {
  1014.    
  1015.     closesocket(m_s);
  1016.     m_s=0;
  1017.     return 0;
  1018. }
  1019.  
  1020.  
  1021. bool IOTCPSocket::StartThread(bool bRestart)
  1022. {
  1023.     m_bRestart=bRestart;
  1024.  
  1025.     m_hThread = CreateThread(NULL, 0, (DWORD (__stdcall *)(LPVOID))&this->RunLoop, this, 0, &m_nThreadID);
  1026.     if (m_hThread) return true;
  1027.     else return false;
  1028. }
  1029.  
  1030. bool IOTCPSocket::StopThread(const bool bAutoTerminate)
  1031. {
  1032.     if (!m_bRunning) return true;   //no thread
  1033.  
  1034.     while (PostThreadMessage(m_nThreadID, WMSQB_EXIT, 0, NULL) == 0)
  1035.         Sleep(100);
  1036.  
  1037.     if(!bAutoTerminate) {
  1038.         if (WaitForSingleObject(m_hThread, 50000) == WAIT_OBJECT_0)
  1039.             return true;    //OK
  1040.         else
  1041.             return false;  
  1042.     }
  1043.     return true;
  1044. }
  1045.  
  1046. void *IOTCPSocket::RunLoop(void *pThis)
  1047. {
  1048.     MSG msg;
  1049.     IOTCPSocket *pIO;
  1050.     pIO=(IOTCPSocket*)pThis;
  1051.  
  1052.     pIO->m_bRunning=true;
  1053.  
  1054.     do {
  1055.         if (pIO->RunOnce()==-1) break;
  1056.         if (PeekMessage(&msg,0, WMSQB_EXIT, WMSQB_EXIT, PM_NOREMOVE) != 0)
  1057.             break;
  1058.     } while (pIO->m_bRestart);
  1059.  
  1060.     pIO->m_bRunning=false;
  1061.     return NULL;
  1062. }
  1063.  
  1064. int IOTCPSocket::RunOnce()
  1065. {
  1066.     int ret=0;
  1067.  
  1068.     if (m_bCommandToSend && m_bDisconnected) {
  1069.         m_s=TCPIO_Connect();
  1070.         if (m_s==0) {
  1071.             IfDisconnected();
  1072.         } else m_bDisconnected=false;
  1073.     }
  1074.  
  1075.     if (!m_bDisconnected && m_bCommandToSend && TCPIO_WSelect()>0) {
  1076.         ret=SendOutput();
  1077.         if (ret==-1) {
  1078.             IfDisconnected();
  1079.         }
  1080.         m_bCommandToSend=false;
  1081.     }
  1082.  
  1083.  
  1084.     if (!m_bDisconnected && TCPIO_RSelect()>0) {
  1085.         ret=GetInput();
  1086.         if (ret==-1) {
  1087.             IfDisconnected();
  1088.         }
  1089.     }
  1090.  
  1091.     Sleep(100);
  1092.  
  1093.     return 0;
  1094. }
  1095.  
  1096.  
  1097.  
  1098.  
  1099. int IOTCPSocket::SendCommand(std::wstring swCommand)
  1100. {
  1101.     BYTE* pBuffer=NULL;
  1102.     unsigned int nBufLen=0;
  1103.     ParseCommand(swCommand, (char **)&pBuffer, &nBufLen);
  1104.     int ret = SendBuffer(pBuffer, nBufLen);
  1105.     free(pBuffer);
  1106.     return ret;
  1107. }
  1108.  
  1109. int IOTCPSocket::GetInput()
  1110. {
  1111. int ret=0;
  1112. BYTE *pBuffer;
  1113. unsigned int nBufLen=0;
  1114.  
  1115.     // Check connected socket
  1116.     ret=TCPIO_Recv(&pBuffer,&nBufLen);
  1117.     if(ret<0) {
  1118.         return -1;
  1119.     }
  1120.     if (ret ==0) {
  1121.     }
  1122.            
  1123.     if(ret>0) {
  1124.         // Breakdown command into response
  1125.         if (nBufLen>0) {
  1126.             EnterCriticalSection(&m_CriticalSection);
  1127.             ret = ParseAnswer((char*)pBuffer, nBufLen);
  1128.             LeaveCriticalSection(&m_CriticalSection);
  1129.  
  1130.             std::free(pBuffer);
  1131.         }
  1132.     }  
  1133.     return ret;
  1134. }
  1135.  
  1136.  
  1137. //OK
  1138. int IOTCPSocket::TCPIO_Init(void)
  1139. {
  1140.     WSADATA wsaData;
  1141.     WORD wVersionRequested = MAKEWORD(2, 2);
  1142.     int err = WSAStartup(wVersionRequested, &wsaData );
  1143.     if (err != 0) return -1;
  1144.     return 1;
  1145. }
  1146.  
  1147.  
  1148.  
  1149.  
  1150. //OK
  1151. SOCKADDR_IN* IOTCPSocket::TCPIO_CreateSOCKADDR(const char *sTarget)
  1152. {
  1153.     // Get target port
  1154.     char svHost[256],*sPort,*sptr;
  1155.     strncpy(svHost,sTarget,256);
  1156.     svHost[255] = '\0';
  1157.     for(sptr=svHost;((*sptr)!=':') && (*sptr);sptr++);
  1158.     if((*sptr)==':') {
  1159.         *sptr='\0';
  1160.         sptr++;
  1161.         sPort=sptr;
  1162.     }
  1163.     else {
  1164.         return 0;
  1165.     }
  1166.  
  1167.     // Resolve hostname
  1168.     SOCKADDR_IN* saddr;
  1169.     saddr = (SOCKADDR_IN*)malloc(sizeof(SOCKADDR_IN));
  1170.  
  1171.     SOCKADDR_IN* sockaddr_ipv4=NULL;
  1172.  
  1173.     struct addrinfo *result = NULL;
  1174.     struct addrinfo *ptr = NULL;
  1175.        
  1176.     int gRet = getaddrinfo(  svHost, sPort, NULL, &result);
  1177.     if(gRet!=0) {
  1178.         return 0;
  1179.     }
  1180.     for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {
  1181.  
  1182.         switch (ptr->ai_family) {
  1183.             case AF_INET:
  1184.                 sockaddr_ipv4 = (struct sockaddr_in *) ptr->ai_addr;
  1185.                 break;
  1186.             default:
  1187.                 break;
  1188.         }
  1189.         if (sockaddr_ipv4!=NULL) break;
  1190.        }
  1191.  
  1192.     if (sockaddr_ipv4==NULL) {
  1193.         freeaddrinfo(result);
  1194.         return NULL;
  1195.     }
  1196.  
  1197.     // Create socket address
  1198.     std::memcpy(saddr,sockaddr_ipv4,sizeof(SOCKADDR_IN));
  1199.     freeaddrinfo(result);
  1200.  
  1201.     return saddr;
  1202. }
  1203.  
  1204.  
  1205.  
  1206. //OK
  1207. int IOTCPSocket::TCPIO_WSelect()
  1208. {
  1209.     int ret;
  1210.     TIMEVAL tm;
  1211.     fd_set wfds;
  1212.     FD_ZERO(&wfds);
  1213.     FD_SET(m_s,&wfds);
  1214.     tm.tv_sec=0;
  1215.     tm.tv_usec=0;
  1216.     ret=select((int)m_s+1,NULL,&wfds,NULL,&tm);
  1217.     return ret;
  1218. }
  1219.  
  1220. //OK
  1221. int IOTCPSocket::TCPIO_RSelect()
  1222. {
  1223.     int ret;
  1224.     TIMEVAL tm;
  1225.     fd_set rfds;
  1226.     FD_ZERO(&rfds);
  1227.     FD_SET(m_s,&rfds);
  1228.     tm.tv_sec=0;
  1229.     tm.tv_usec=0;
  1230.     ret=select((int)m_s+1,&rfds,NULL,NULL,&tm);
  1231.     return ret;
  1232. }
  1233.  
  1234.  
  1235. //OK
  1236. int IOTCPSocket::SendBuffer(BYTE *pBuffer, unsigned int len)
  1237. {
  1238.     if ( (pBuffer == NULL) )
  1239.         return 0;
  1240.  
  1241.     BYTE *buf;
  1242.     int ret;
  1243.  
  1244.     int pos=0;
  1245.     int size=0;
  1246.     unsigned int lBufLen;
  1247.  
  1248.     if(len==0) {
  1249.         return 0;
  1250.     } else {
  1251.         while(len>0) {
  1252.             size=((len-pos)<SIZE_MTU ) ? len : SIZE_MTU;
  1253.             buf=AllocatePacket((BYTE *)pBuffer+pos, size, &lBufLen);
  1254.             ret = TCPIO_Send(buf, lBufLen);
  1255.             free(buf);     
  1256.        
  1257.             pos+=size;
  1258.             len-=size;
  1259.             if (ret==SOCKET_ERROR) break;
  1260.         }
  1261.     }
  1262.     return ret;
  1263. }
  1264.  
  1265.  
  1266. //OK
  1267. BYTE *IOTCPSocket::AllocatePacket(BYTE *pBuffer, unsigned int size, unsigned int *nPktLen)
  1268. {
  1269.     BYTE *pTemp;
  1270.     int buflen=0;
  1271.    
  1272.  
  1273.     if(pBuffer!=NULL) {
  1274.         buflen = size;
  1275.     }
  1276.    
  1277.  
  1278.     pTemp=(BYTE *) malloc(buflen);
  1279.     if(pTemp==NULL) {
  1280.         return NULL;
  1281.     }
  1282.  
  1283.     if(pBuffer!=NULL) {
  1284.         std::memcpy(pTemp,pBuffer,size);
  1285.     }
  1286.     *nPktLen=buflen;
  1287.     return pTemp;
  1288. }
  1289.  
  1290. //OK
  1291. int IOTCPSocket::TCPIO_Send(const BYTE *pData, unsigned int nDataLen)
  1292. {
  1293.     // Make single packet
  1294.     void *pkt=malloc(nDataLen);
  1295.     if(pkt==NULL) {
  1296.         return -1;
  1297.     }
  1298.  
  1299.     std::memcpy((BYTE *)pkt,pData,nDataLen);
  1300.    
  1301.     // Send packet
  1302.     int ret;
  1303.     char *ppkt=(char *)pkt;
  1304.     int count=nDataLen;
  1305.     do {
  1306.         ret=send(m_s,ppkt,count,0);
  1307.         if(ret==SOCKET_ERROR) {
  1308.             break;
  1309.         }
  1310.  
  1311.         count-=ret;
  1312.         ppkt+=ret;
  1313.         //if(count>0) Sleep(20);
  1314.     } while(count>0);
  1315.     free(pkt);
  1316.     return ret;
  1317. }
  1318.  
  1319.  
  1320.  
  1321. int IOTCPSocket::TCPIO_Recv(BYTE **pInData, unsigned int *pnInDataLen)
  1322. {
  1323.     *pnInDataLen=0;
  1324.     *pInData=NULL;
  1325.     if (m_s==0) {
  1326.         return -1;
  1327.     }
  1328.    
  1329.     // Get length of rest of data
  1330.     DWORD nPktLen=SIZE_BUF64;
  1331.     int lenret;
  1332.     // Allocate buffer for data
  1333.     BYTE *buf=(BYTE *)std::malloc(nPktLen+2);
  1334.     if(buf==NULL) {
  1335.         return -1;
  1336.     }
  1337.  
  1338.     int i=0;
  1339.     while (i<nPktLen+2) {
  1340.         buf[i]=0xAA;
  1341.         i++;
  1342.     }
  1343.  
  1344.     // Receive data
  1345.     char *pbuf=(char *)buf;
  1346.     int count=nPktLen;
  1347.     do {
  1348.         lenret=recv(m_s,pbuf,count,0);
  1349.         if(lenret==0) {
  1350.             //Disconnection from server
  1351.             free(buf);
  1352.             *pInData=NULL;
  1353.             *pnInDataLen=0;
  1354.             return -1;
  1355.         }
  1356.         if(lenret==SOCKET_ERROR) {
  1357.             if (WSAEWOULDBLOCK != WSAGetLastError()) {
  1358.                 free(buf);
  1359.                 *pInData=NULL;
  1360.                 *pnInDataLen=0;
  1361.                 return -1;
  1362.             }
  1363.             break;
  1364.         }
  1365.         count-=lenret;
  1366.         pbuf+=lenret;
  1367.         *pnInDataLen+=lenret;
  1368.         if(lenret!=0 && lenret<count ) {
  1369.             break;
  1370.         }
  1371.         //if(count>0) Sleep(20);
  1372.     } while(count>0);
  1373.  
  1374.     // Pass data back to application
  1375.     pbuf[0]=0;
  1376.     *pInData=buf;
  1377.     return 1;
  1378. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement