// . return ptr to the buffer we serialize into // . return NULL and set g_errno on error bool Msg20Reply::sendReply ( XmlDoc *xd ) { // get it UdpSlot *slot = (UdpSlot *)xd->m_slot; if ( g_errno ) { // extract titleRec ptr log("query: Had error generating msg20 reply for d=%lli: " "%s",m_docId, mstrerror(g_errno)); // don't forget to delete this list haderror: mdelete ( xd, sizeof(XmlDoc) , "Msg20" ); delete ( xd ); g_udpServer.sendErrorReply ( slot , g_errno ) ; return true; } // now create a buffer to store title/summary/url/docLen and send back long need = getStoredSize(); char *buf = (char *)mmalloc ( need , "Msg20Reply" ); if ( ! buf ) goto haderror; // should never have an error! long used = serialize ( buf , need ); // sanity if ( used != need ) { char *xx=NULL;*xx=0; } // sanity check, no, might have been banned/filtered above around // line 956 and just called sendReply directly //if ( st->m_memUsed == 0 ) { char *xx=NULL;*xx=0; } // use blue for our color long color = 0x0000ff; // but use dark blue for niceness > 0 if ( xd->m_niceness > 0 ) color = 0x0000b0; //Msg20Reply *tt = (Msg20Reply *)buf; // sanity check if ( ! xd->m_utf8ContentValid ) { char *xx=NULL;*xx=0; } // for records long clen = 0; if ( xd->m_utf8ContentValid ) clen = xd->size_utf8Content - 1; // show it in performance graph if ( xd->m_startTimeValid ) g_stats.addStat_r ( clen , xd->m_startTime , gettimeofdayInMilliseconds() , color ); // . del the list at this point, we've copied all the data into reply // . this will free a non-null State20::m_ps (ParseState) for us mdelete ( xd , sizeof(XmlDoc) , "xd20" ); delete ( xd ); g_udpServer.sendReply_ass ( buf , need , buf , need , slot ); return true; }
int32_t Msg2b::serialize ( char *buf, int32_t bufLen ) { // make sure we have room int32_t storedSize = getStoredSize(); if (bufLen < storedSize) return -1; char *p = buf; // m_dirId + m_numSubCats + m_catBufferLen *(int32_t *)p = m_dirId; p += sizeof(int32_t); *(int32_t *)p = m_numSubCats; p += sizeof(int32_t); *(int32_t *)p = m_catBufferLen; p += sizeof(int32_t); // sub cats gbmemcpy(p, m_subCats, sizeof(SubCategory)*m_numSubCats); p += sizeof(SubCategory)*m_numSubCats; // cat buffer gbmemcpy(p, m_catBuffer, m_catBufferLen); p += m_catBufferLen; // sanity check if (p - buf != storedSize) { log("Msg2b: Bad serialize size, %i != %"INT32", bad engineer.", p - buf, storedSize); char *xx = NULL; *xx = 0; } // return bytes stored return storedSize; }
// . returns # bytes written into "buf" // . returns ptr to buf used // . set size of buf allocated and used // . returns -1 on error char *HashTableX::serialize ( long *bufSize ) { long need = getStoredSize(); char *buf = (char *)mmalloc ( need , m_allocName ); if ( ! buf ) return (char *)-1; long used = serialize ( buf , need ); // ensure it matches if ( used != need ) { char *xx=NULL;*xx=0; } // store it *bufSize = used; return buf; }
// . return ptr to the buffer we serialize into // . return NULL and set g_errno on error char *Msg20Request::serialize(int32_t *retSize) const { // make a buffer to serialize into int32_t need = getStoredSize(); // alloc if we should char *buf = (char *)mmalloc ( need , "Msg20Ra" ); // bail on error, g_errno should be set if ( ! buf ) return NULL; return serializeMsg(sizeof(*this), &size_qbuf, &size_displayMetas, &ptr_qbuf, this, retSize, buf, need); }
// . return ptr to the buffer we serialize into // . return NULL and set g_errno on error char *Msg20Request::serialize ( long *retSize , char *userBuf , long userBufSize ) { // make a buffer to serialize into char *buf = NULL; long need = getStoredSize(); // big enough? if ( need <= userBufSize ) buf = userBuf; // alloc if we should if ( ! buf ) buf = (char *)mmalloc ( need , "Msg20Ra" ); // bail on error, g_errno should be set if ( ! buf ) return NULL; // set how many bytes we will serialize into *retSize = need; // copy the easy stuff char *p = buf; memcpy ( p , (char *)this , sizeof(Msg20Request) ); p += (long)sizeof(Msg20Request); // then store the strings! long *sizePtr = &size_qbuf; long *sizeEnd = &size_displayMetas; char **strPtr = &ptr_qbuf; for ( ; sizePtr <= sizeEnd ; ) { // sanity check -- cannot copy onto ourselves if ( p > *strPtr && p < *strPtr + *sizePtr ) { char *xx = NULL; *xx = 0; } // copy the string into the buffer memcpy ( p , *strPtr , *sizePtr ); // advance our destination ptr p += *sizePtr; // advance both ptrs to next string sizePtr++; strPtr++; } return buf; }
// . return ptr to the buffer we serialize into // . return NULL and set g_errno on error bool Msg20Reply::sendReply(Msg20State *state) { if ( g_errno ) { // extract titleRec ptr log(LOG_ERROR, "query: Had error generating msg20 reply for d=%" PRId64": %s",state->m_xmldoc.m_docId, mstrerror(g_errno)); // don't forget to delete this list haderror: UdpSlot *slot = state->m_slot; mdelete(state, sizeof(*state), "Msg20"); delete state; log(LOG_ERROR,"%s:%s:%d: call sendErrorReply. error=%s", __FILE__, __func__, __LINE__, mstrerror( g_errno )); g_udpServer.sendErrorReply(slot, g_errno); return true; } // now create a buffer to store title/summary/url/docLen and send back int32_t need = getStoredSize(); char *buf = (char *)mmalloc ( need , "Msg20Reply" ); if ( ! buf ) goto haderror; // should never have an error! int32_t used = serialize ( buf , need ); // sanity if ( used != need ) { g_process.shutdownAbort(true); } // use blue for our color int32_t color = 0x0000ff; // but use dark blue for niceness > 0 if ( state->m_xmldoc.m_niceness > 0 ) color = 0x0000b0; // sanity check if ( ! state->m_xmldoc.m_utf8ContentValid ) { g_process.shutdownAbort(true); } // for records int32_t clen = 0; if ( state->m_xmldoc.m_utf8ContentValid ) clen = state->m_xmldoc.size_utf8Content - 1; // show it in performance graph if ( state->m_xmldoc.m_startTimeValid ) { g_stats.addStat_r( clen, state->m_xmldoc.m_startTime, gettimeofdayInMilliseconds(), color ); } //put the reply into the summary cache if(m_isDisplaySumSetFromTags && !state->m_req->m_highlightQueryTerms) g_stable_summary_cache.insert(state->m_req->makeCacheKey(), buf, need); else g_unstable_summary_cache.insert(state->m_req->makeCacheKey(), buf, need); UdpSlot *slot = state->m_slot; // . del the list at this point, we've copied all the data into reply // . this will free a non-null State20::m_ps (ParseState) for us mdelete(state, sizeof(*state), "Msg20"); delete state; g_udpServer.sendReply(buf, need, buf, need, slot); return true; }