STATIC void EXPAT_StartElement(void * ctx, XML_Str tag, XML_Str * atts) { ExpatContext * expat = (ExpatContext *)ctx; if (expat->cb.startElem) { XMLAttr aset; XML_Str * s = atts; BUFFER_Clear(&expat->buf); BUFFER_Clear(&expat->atts); while (*s) { wchar_t* ws; XML_Str xs = *s++; /* * store offset in the vector - later will be replaces with the * pointer. Cannot store the pointers now because buffer may be * reallocated during conversion. */ const int off = BUFFER_Size(&expat->buf)/sizeof(Char); BUFFER_Put(&expat->atts, &off, sizeof(off), False); /* Convert from UTF-8 XML_Str to Str */ ws = STRING_ToUnicode(xs); if (ws) { #ifdef UNICODE BUFFER_Put(&expat->buf,ws,(wcslen(ws)+1)*sizeof(ws[0]),False); #else char * mb = STRING_ToMultiByte(ws); if (mb) { BUFFER_Put(&expat->buf, mb, strlen(mb)+1, False); MEM_Free(mb); } else { BUFFER_Put(&expat->buf, xs, strlen(xs)+1, False); } #endif MEM_Free(ws); } } ASSERT(!((BUFFER_Size(&expat->atts)/sizeof(int))%2)); aset.storage = BUFFER_Access(&expat->buf); aset.size = BUFFER_Size(&expat->buf); aset.off = BUFFER_Access(&expat->atts); aset.n = BUFFER_Size(&expat->atts)/sizeof(int)/2; EXPAT_ConvertTag(&expat->sb, tag); (*expat->cb.startElem)(expat->ctx, STRBUF_Text(&expat->sb), &aset); } }
STATIC void EXPAT_StartElement(void * ctx, XML_Str tag, XML_Str * atts) { ExpatContext * expat = (ExpatContext *)ctx; if (expat->cb.startElem) { XMLAttr aset; XML_Str * s = atts; BUFFER_Clear(&expat->buf); VECTOR_Clear(&expat->atts); while (*s) { Char tmp; const XML_Char * c = (*s); /* * store offset in the vector - later will be replaces with the * pointer. Cannot store the pointers now because buffer may be * reallocated during conversion. */ int off = BUFFER_Size(&expat->buf)/sizeof(Char); VECTOR_Add(&expat->atts,(VElement)(PtrWord)off); /* * Pretty naive convertion of attribute names and values from * XML_Str to Str. This part may need some improvement... */ while (*c) { tmp = (Char)*c; BUFFER_Put(&expat->buf, &tmp, sizeof(tmp), False); c++; } tmp = 0; BUFFER_Put(&expat->buf, &tmp, sizeof(tmp), False); s++; } ASSERT(!(VECTOR_Size(&expat->atts)%2)); aset.storage = (Char*)BUFFER_Access(&expat->buf); aset.size = BUFFER_Size(&expat->buf); aset.off = (int*)VECTOR_GetElements(&expat->atts); aset.n = VECTOR_Size(&expat->atts)/2; EXPAT_ConvertTag(&expat->sb, tag); (*expat->cb.startElem)(expat->ctx, STRBUF_Text(&expat->sb), &aset); } }
STATIC void EXPAT_Characters(void * ctx, XML_Str s, int len) { ExpatContext * expat = (ExpatContext *)ctx; if (expat->cb.charData) { const wchar_t * chars; #if defined(XML_UNICODE_WCHAR_T) || defined(_WIN32) chars = s; #else /* !XML_UNICODE_WCHAR_T && !_WIN32 */ int i; wchar_t wc; BUFFER_Clear(&expat->buf); for (i=0; i<len; i++) { wc = s[i]; if (!BUFFER_Put(&expat->buf,&wc,sizeof(wc),False)) { break; } } wc = 0; BUFFER_Put(&expat->buf,&wc,sizeof(wc),False); chars = (wchar_t*)BUFFER_Access(&expat->buf); #endif /* !XML_UNICODE_WCHAR_T && !_WIN32 */ (*expat->cb.charData)(expat->ctx, chars, len); } }
STATIC Bool GWENG_QueueWrite(EcmtConnection* c, const void* data, int size) { EcmtQueueConnection* qc = CAST(c,EcmtQueueConnection,connection); /* * Try to avoid copying. Most of the time we can safely do that because * both header and data are written as single chunks. However, if they * are not so nicely packaged, we have plan B. */ if (!BUFFER_Size(&qc->buf)) { if (qc->header && size>=ECMT_MSG_HEADER_SIZE) { if (GWENG_ParseEcmtHeader(data, &qc->uid, &qc->datalen)) { data = ((char*)data) + ECMT_MSG_HEADER_SIZE; size -= ECMT_MSG_HEADER_SIZE; qc->datalen -= ECMT_MSG_HEADER_SIZE; qc->header = False; } else { /* There shoudn't be any garbage here */ ASSMSG("Garbage in GWENG_QueueWrite"); return False; } } if (!qc->header && size >= qc->datalen) { GWENG_QueueAdd(qc->queue, qc->uid, data, qc->datalen); data = ((char*)data) + qc->datalen; size -= qc->datalen; qc->uid = 0; qc->datalen = 0; qc->header = True; } } if (size > 0) { /* Plan B */ if (BUFFER_Put(&qc->buf, data, size, False) == size) { while (GWENG_QueueFlush(qc)); } else { return False; } } return True; }