static bool array_iterator_is_valid(const void *collection, void **state) { as_t *s; assert(NULL != state); assert(NULL != *state); s = (as_t *) *state; return s->ptr >= CHAR_P(collection) && s->ptr < CHAR_P(collection) + s->element_count * s->element_size; }
// // Read packet from socket // INT_32 FastCGIIO::ReadPacket(void * vReadBuffer, const INT_32 iPacketLen) { INT_32 iTotalRead = 0; INT_32 iNeedRead = iPacketLen; for(;;) { if (PollSocket(POLLIN) < 0) { return -1; } INT_32 iReadBytes = 0; do { iReadBytes = read(iClientSocket, CHAR_P(vReadBuffer) + iTotalRead, iNeedRead); } while (iReadBytes == -1 && errno == EINTR); if (iReadBytes <= 0) { return -1; } oWorkerContext.bytes_read += iReadBytes; iTotalRead += iReadBytes; iNeedRead -= iReadBytes; if (iTotalRead == iPacketLen) { return iPacketLen; } } return -1; }
static void null_sentineled_field_terminated_array_iterator_current(const void *collection, void **state, void **key, void **value) { nsftas_t *s; assert(NULL != state); assert(NULL != value); s = (nsftas_t *) *state; if (NULL != value) { *value = (void *) s->ptr; } if (NULL != key) { *((uint64_t *) key) = (s->ptr - CHAR_P(collection)) / s->element_size; } }
static void array_iterator_current(const void *collection, void **state, void **key, void **value) { as_t *s; assert(NULL != state); assert(NULL != value); s = (as_t *) *state; if (NULL != value) { memcpy((char *) value, s->ptr, s->element_size); } if (NULL != key) { *((uint64_t *) key) = (s->ptr - CHAR_P(collection)) / s->element_size; } }
/** * Iterate on an array of struct (or union) where one of its field is sentineled * by a NULL pointer. * * @param it the iterator to initialize * @param array the array to iterate on * @param element_size the size of an element of this array * @param field_offset the offset of the member to test against NULL * (use offsetof to define it) */ void null_sentineled_field_terminated_array_to_iterator(Iterator *it, void *array, size_t element_size, size_t field_offset) { nsftas_t *s; s = malloc(sizeof(*s)); s->ptr = CHAR_P(array); s->element_size = element_size; s->field_offset = field_offset; iterator_init( it, array, s, null_sentineled_field_terminated_array_iterator_first, NULL, null_sentineled_field_terminated_array_iterator_current, null_sentineled_field_terminated_array_iterator_next, NULL, null_sentineled_field_terminated_array_iterator_is_valid, free ); }
/** * Iterate on an array of struct (or union) where one of its field is sentineled * by a NULL pointer. * * @param it the iterator to initialize * @param array the array to iterate on * @param element_size the size of an element of this array * @param element_count the number of elements in the array */ void array_to_iterator(Iterator *it, void *array, size_t element_size, size_t element_count) { as_t *s; s = malloc(sizeof(*s)); s->ptr = CHAR_P(array); s->element_size = element_size; s->element_count = element_count; iterator_init( it, array, s, array_iterator_first, array_iterator_last, array_iterator_current, array_iterator_next, array_iterator_prev, array_iterator_is_valid, free ); }
/** * Processes the passed-in node to generate a ForecastInfo entry * * @param pNode Pointer to the XML Channel Node. * @param pEntry Pointer to the ForecastInfo entry to be filled in. * * @return A newly created ForecastInfo entry on success, or NULL on failure. */ static gpointer processChannelNode(xmlNodePtr pNode, ForecastInfo * pEntry) { if (!pNode) { return NULL; } xmlNodePtr pCurr = pNode->xmlChildrenNode; for (; pCurr != NULL; pCurr = pCurr->next) { if (pCurr->type == XML_ELEMENT_NODE) { if (xmlStrEqual(pCurr->name, CONSTXMLCHAR_P("title"))) { /* Evaluate title to see if there was an error */ char * pcContent = CHAR_P(xmlNodeListGetString(pCurr->doc, pCurr->xmlChildrenNode, 1)); if (strstr(pcContent, "Error")) { xmlFree(XMLCHAR_P(pcContent)); do { pCurr = pCurr->next; } while (pCurr && !xmlStrEqual(pCurr->name, CONSTXMLCHAR_P("item"))); xmlNodePtr pChild = (pCurr)?pCurr->xmlChildrenNode:NULL; for (; pChild != NULL; pChild = pChild->next) { if (pChild->type == XML_ELEMENT_NODE && xmlStrEqual(pChild->name, CONSTXMLCHAR_P("title"))) { pcContent = CHAR_P(xmlNodeListGetString(pChild->doc, pChild->xmlChildrenNode, 1)); LXW_LOG(LXW_ERROR, "yahooutil::processChannelNode(): Forecast retrieval error: %s", pcContent); xmlFree(XMLCHAR_P(pcContent)); } } return NULL; } else { xmlFree(XMLCHAR_P(pcContent)); /* ...and continue... */ } } else if (xmlStrEqual(pCurr->name, CONSTXMLCHAR_P("item"))) { /* item child element gets 'special' treatment */ processItemNode((gpointer *)&pEntry, pCurr); } else if (xmlStrEqual(pCurr->name, CONSTXMLCHAR_P("units"))) { // distance const char * pczDistance = CONSTCHAR_P(xmlGetProp(pCurr, XMLCHAR_P("distance"))); gsize distanceLength = ((pczDistance)?strlen(pczDistance):0); setStringIfDifferent(&pEntry->units_.pcDistance_, pczDistance, distanceLength); xmlFree(XMLCHAR_P(pczDistance)); // pressure const char * pczPressure = CONSTCHAR_P(xmlGetProp(pCurr, XMLCHAR_P("pressure"))); gsize pressureLength = ((pczPressure)?strlen(pczPressure):0); setStringIfDifferent(&pEntry->units_.pcPressure_, pczPressure, pressureLength); xmlFree(XMLCHAR_P(pczPressure)); // speed const char * pczSpeed = CONSTCHAR_P(xmlGetProp(pCurr, XMLCHAR_P("speed"))); gsize speedLength = ((pczSpeed)?strlen(pczSpeed):0); setStringIfDifferent(&pEntry->units_.pcSpeed_, pczSpeed, speedLength); xmlFree(XMLCHAR_P(pczSpeed)); // temperature const char * pczTemperature = CONSTCHAR_P(xmlGetProp(pCurr, XMLCHAR_P("temperature"))); gsize temperatureLength = ((pczTemperature)?strlen(pczTemperature):0); setStringIfDifferent(&pEntry->units_.pcTemperature_, pczTemperature, temperatureLength); xmlFree(XMLCHAR_P(pczTemperature)); } else if (xmlStrEqual(pCurr->name, CONSTXMLCHAR_P("wind"))) { // chill const char * pczChill = CONSTCHAR_P(xmlGetProp(pCurr, XMLCHAR_P("chill"))); setIntIfDifferent(&pEntry->iWindChill_, pczChill); xmlFree(XMLCHAR_P(pczChill)); // direction const char * pczDirection = CONSTCHAR_P(xmlGetProp(pCurr, XMLCHAR_P("direction"))); gint iValue = (gint)g_ascii_strtoll((pczDirection)?pczDirection:"999", NULL, 10); const gchar * pczDir = WIND_DIRECTION(iValue); setStringIfDifferent(&pEntry->pcWindDirection_, pczDir, strlen(pczDir)); xmlFree(XMLCHAR_P(pczDirection)); // speed const char * pczSpeed = CONSTCHAR_P(xmlGetProp(pCurr, XMLCHAR_P("speed"))); setIntIfDifferent(&pEntry->iWindSpeed_, pczSpeed); xmlFree(XMLCHAR_P(pczSpeed)); } else if (xmlStrEqual(pCurr->name, CONSTXMLCHAR_P("atmosphere"))) { // humidity const char * pczHumidity = CONSTCHAR_P(xmlGetProp(pCurr, XMLCHAR_P("humidity"))); setIntIfDifferent(&pEntry->iHumidity_, pczHumidity); xmlFree(XMLCHAR_P(pczHumidity)); // pressure const char * pczPressure = CONSTCHAR_P(xmlGetProp(pCurr, XMLCHAR_P("pressure"))); pEntry->dPressure_ = g_ascii_strtod((pczPressure)?pczPressure:"0", NULL); xmlFree(XMLCHAR_P(pczPressure)); // visibility const char * pczVisibility = CONSTCHAR_P(xmlGetProp(pCurr, XMLCHAR_P("visibility"))); pEntry->dVisibility_ = g_ascii_strtod((pczVisibility)?pczVisibility:"0", NULL); // need to divide by 100 //pEntry->dVisibility_ = pEntry->dVisibility_/100; xmlFree(XMLCHAR_P(pczVisibility)); // state const char * pczState = CONSTCHAR_P(xmlGetProp(pCurr, XMLCHAR_P("rising"))); pEntry->pressureState_ = (PressureState)g_ascii_strtoll((pczState)?pczState:"0", NULL, 10); xmlFree(XMLCHAR_P(pczState)); } else if (xmlStrEqual(pCurr->name, CONSTXMLCHAR_P("astronomy"))) { // sunrise const char * pczSunrise = CONSTCHAR_P(xmlGetProp(pCurr, XMLCHAR_P("sunrise"))); gsize sunriseLength = ((pczSunrise)?strlen(pczSunrise):0); setStringIfDifferent(&pEntry->pcSunrise_, pczSunrise, sunriseLength); xmlFree(XMLCHAR_P(pczSunrise)); // sunset const char * pczSunset = CONSTCHAR_P(xmlGetProp(pCurr, XMLCHAR_P("sunset"))); gsize sunsetLength = ((pczSunset)?strlen(pczSunset):0); setStringIfDifferent(&pEntry->pcSunset_, pczSunset, sunsetLength); xmlFree(XMLCHAR_P(pczSunset)); } } } return pEntry; }
/** * Processes the passed-in node to generate a LocationInfo entry * * @param pEntry Pointer to the pointer to the ForecastInfo entry being filled. * @param pNode Pointer to the XML Item Node. * * @return 0 on success, -1 on failure */ static gint processItemNode(gpointer * pEntry, xmlNodePtr pNode) { if (!pNode || !pEntry) { return -1; } ForecastInfo * pInfo = *((ForecastInfo **)pEntry); xmlNodePtr pCurr = pNode->xmlChildrenNode; int iForecastCount = 0; for (; pCurr != NULL; pCurr = pCurr->next) { if (pCurr->type == XML_ELEMENT_NODE) { if (xmlStrEqual(pCurr->name, CONSTXMLCHAR_P("condition"))) { const char * pczDate = CONSTCHAR_P(xmlGetProp(pCurr, XMLCHAR_P("date"))); const char * pczTemp = CONSTCHAR_P(xmlGetProp(pCurr, XMLCHAR_P("temp"))); const char * pczText = CONSTCHAR_P(xmlGetProp(pCurr, XMLCHAR_P("text"))); gsize dateLength = ((pczDate)?strlen(pczDate):0); gsize textLength = ((pczText)?strlen(pczText):0); setStringIfDifferent(&pInfo->pcTime_, pczDate, dateLength); setIntIfDifferent(&pInfo->iTemperature_, pczTemp); setStringIfDifferent(&pInfo->pcConditions_, pczText, textLength); xmlFree(XMLCHAR_P(pczDate)); xmlFree(XMLCHAR_P(pczTemp)); xmlFree(XMLCHAR_P(pczText)); } else if (xmlStrEqual(pCurr->name, CONSTXMLCHAR_P("description"))) { char * pcContent = CHAR_P(xmlNodeListGetString(pCurr->doc, pCurr->xmlChildrenNode, 1)); char * pcSavePtr = NULL; // initial call to find the first '"' strtok_r(pcContent, "\"", &pcSavePtr); // second call to find the second '"' char * pcImageURL = strtok_r(NULL, "\"", &pcSavePtr); // found the image if (pcImageURL && strstr(pcImageURL, "yimg.com")) { LXW_LOG(LXW_DEBUG, "yahooutil::processItemNode(): IMG URL: %s", pcImageURL); setImageIfDifferent(&pInfo->pcImageURL_, &pInfo->pImage_, pcImageURL, strlen(pcImageURL)); } xmlFree(XMLCHAR_P(pcContent)); } else if (xmlStrEqual(pCurr->name, CONSTXMLCHAR_P("forecast"))) { ++iForecastCount; const char * pczDay = CONSTCHAR_P(xmlGetProp(pCurr, XMLCHAR_P("day"))); const char * pczHigh = CONSTCHAR_P(xmlGetProp(pCurr, XMLCHAR_P("high"))); const char * pczLow = CONSTCHAR_P(xmlGetProp(pCurr, XMLCHAR_P("low"))); const char * pczText = CONSTCHAR_P(xmlGetProp(pCurr, XMLCHAR_P("text"))); gsize dayLength = ((pczDay)?strlen(pczDay):0); gsize textLength = ((pczText)?strlen(pczText):0); if (iForecastCount == 1) { setStringIfDifferent(&pInfo->today_.pcDay_, pczDay, dayLength); setIntIfDifferent(&pInfo->today_.iHigh_, pczHigh); setIntIfDifferent(&pInfo->today_.iLow_, pczLow); setStringIfDifferent(&pInfo->today_.pcConditions_, pczText, textLength); } else { setStringIfDifferent(&pInfo->tomorrow_.pcDay_, pczDay, dayLength); setIntIfDifferent(&pInfo->tomorrow_.iHigh_, pczHigh); setIntIfDifferent(&pInfo->tomorrow_.iLow_, pczLow); setStringIfDifferent(&pInfo->tomorrow_.pcConditions_, pczText, textLength); } xmlFree(XMLCHAR_P(pczDay)); xmlFree(XMLCHAR_P(pczHigh)); xmlFree(XMLCHAR_P(pczLow)); xmlFree(XMLCHAR_P(pczText)); } } } return 0; }