2 * Simple wrapper for curl and Yahoo finance queries
3 * to enable grabbing stock data.
6 #include "stockgetter.h"
12 /* Current maximum query return size */
13 #define SG_MAX_BUFFER 512
15 /* Current query string, note the %s for the stock ticker name */
16 #define SG_QUERY_STRING "http://finance.yahoo.com/d/quotes.csv?s=%s&f=l1c"
18 static size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp)
20 StockBuffer *psContext = (StockBuffer*)userp;
21 int nBytes = size * nmemb;
23 /*TODO: Write extendable buffer */
24 if(nBytes > psContext->nCount - psContext->nCurr)
26 fprintf(stderr,"Ran out of buffer space! (Bytes %d, %d/%d)\n",nBytes,psContext->nCurr,psContext->nCount);
30 memcpy((void*)(psContext->pszBuffer + psContext->nCurr),buffer,nBytes);
31 psContext->nCurr += nBytes;
42 hSG = (SGHandle)malloc(sizeof(struct _SGHandle));
47 memset(hSG,0,sizeof(struct _SGHandle));
49 if(curl_global_init(CURL_GLOBAL_ALL) != 0)
52 curl_handle = curl_easy_init();
57 if(curl_easy_setopt(curl_handle,CURLOPT_WRITEFUNCTION,write_data) != 0)
60 if(curl_easy_setopt (curl_handle, CURLOPT_FOLLOWLOCATION, 1) != 0)
63 if(curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA,&hSG->sData) != 0)
66 hSG->hCurlHandle = curl_handle;
79 RetrieveStockPrice(SGHandle hSG,
83 float *pfChangePercent)
85 const char *pszQueryString = SG_QUERY_STRING;
86 char aszQuery[255] = {0};
88 float fChangeReal = 0.0f;
89 float fChangePer = 0.0f;
91 if(!hSG || !pfValue || !szTicker || strlen(szTicker) > 10)
92 return SG_INVALID_PARAMS;
94 /* On first lookup setup output buffer */
95 if(!hSG->sData.pszBuffer)
97 hSG->sData.pszBuffer = (char*)malloc(sizeof(char)*SG_MAX_BUFFER);
99 if(!hSG->sData.pszBuffer)
102 memset(hSG->sData.pszBuffer,0,SG_MAX_BUFFER);
104 hSG->sData.nCount = SG_MAX_BUFFER;
107 sprintf(aszQuery,pszQueryString,szTicker);
109 if(curl_easy_setopt(hSG->hCurlHandle, CURLOPT_URL,aszQuery) != 0)
110 return SG_LOOKUP_FAILURE;
112 if(curl_easy_perform(hSG->hCurlHandle) != 0)
113 return SG_LOOKUP_FAILURE;
115 hSG->sData.nCurr = 0;
117 if(sscanf(hSG->sData.pszBuffer,"%f,\"%f - %f\"\n",&fValue,&fChangeReal,&fChangePer) != 3)
118 return SG_LOOKUP_FAILURE;
124 *pfChangeReal = fChangeReal;
127 *pfChangePercent = fChangePer;
133 FreeStockGetter(SGHandle hSG)
136 return SG_INVALID_PARAMS;
138 curl_easy_cleanup(hSG->hCurlHandle);
139 curl_global_cleanup();