/* Added by MP. */ PRIVATE BOOL HTNewsNode_linkRef (HTNewsNode* node, HTNewsNode* referer) { if (node && referer) { node->refChildren++; node->lastChild = referer; node->minRefIndex = (node->minRefIndex != 0 ? HTMIN(node->minRefIndex, referer->index) : referer->index); node->maxRefIndex = (node->maxRefIndex != 0 ? HTMAX(node->maxRefIndex, referer->index) : referer->index); node->minRefDate = (node->minRefDate != 0 ? HTMIN(node->minRefDate, referer->date) : referer->date); node->maxRefDate = (node->maxRefDate != 0 ? HTMAX(node->maxRefDate, referer->date) : referer->date); referer->refParent = node; return YES; } return NO; }
PUBLIC HTStream * HTStreamToChunk (HTRequest * request, HTChunk ** chunk, int max_size) { if (request) { HTStream * me; *chunk = NULL; if ((me = (HTStream *) HT_CALLOC(1, sizeof(HTStream))) == NULL) HT_OUTOFMEM("HTStreamToChunk"); me->isa = &HTStreamToChunkClass; me->request = request; me->max_size = (!max_size) ? max_size : HT_MAXSIZE; me->chunk = *chunk = HTChunk_new(me->max_size > 0 ? HTMIN(me->max_size, HT_MAXGROWSIZE) : HT_MAXGROWSIZE); HTTRACE(STREAM_TRACE, "ChunkStream. Chunk %p created with max size %d\n" _ me->chunk _ me->max_size); return me; } return HTErrorStream(); }
/* ** Parse through the buffer, identify the headers, and distribute the ** data on the virtual session input streams */ PRIVATE int HTDemux_write (HTStream * me, const char * buf, int len) { HTMuxChannel * muxch = me->muxch; int length = 0; while (len > 0) { /* ** Look for the next header. If this is the first time through then ** we expect the stream of data to start with a header. */ if (!me->next) { HTMuxHeader header[2]; HTMuxSessionId sid = INVSID; header[0] = HT_WORDSWAP(*(HTMuxHeader *) buf); /* ** If the long bit is set then we expect another 32 bits as the ** length of the payload */ if (MUX_IS_LONG(header[0])) { header[1] = HT_WORDSWAP(*(HTMuxHeader *) (buf+1)); me->next = MUX_LONG_ALIGN(header[1]); buf += 8, len -= 8; } else { me->next = MUX_ALIGN(MUX_GET_LEN(header[0])); buf += 4, len -= 4; } length = HTMIN(len, me->next); sid = MUX_GET_SID(header[0]); HTTRACE(MUX_TRACE, "Demux stream Header: %x, sid %d, length %d\n" _ header[0] _ length _ sid); /* ** If this is a control message then handle it here */ if (header[0] & MUX_CONTROL) { if (header[0] & MUX_STRING) { ; /* Define the string */ } else if (header[0] & MUX_STACK) { ; /* Define the stack */ } else if (header[0] & MUX_FRAGMENT) { HTMuxSession_setFragment(muxch, sid, MUX_GET_LEN(header[0])); } else if (header[0] & MUX_CREDIT) { HTMuxSession_setCredit(muxch, sid, header[1]); } } else if (header[0] & MUX_SYN) { me->session = HTMuxSession_register(muxch, sid, MUX_GET_PID(header[0])); } else if (header[0] & MUX_FIN) { me->session = HTMuxChannel_findSession(muxch, sid); HTMuxSession_setClose(me->muxch, me->session, MUX_S_END_READ); } else me->session = HTMuxChannel_findSession(muxch, sid); } /* ** If there is data on this session then handle it here. */ if (me->next && me->session) { if (HTMuxSession_disposeData(me->session, buf, length) == 1) { HTMuxChannel_sendControl(muxch, HTMuxSession_id(me->session), MUX_CREDIT, DEFAULT_CREDIT, NULL, 0); } } buf += length, len -= length, me->next -= length; } return HT_OK; }