int automem_append_voidp(automem_t* pmem, const void* p, unsigned int len) { automem_ensure_newspace(pmem, len); memcpy(pmem->pdata + pmem->size, p, len); pmem->size += len; return len; }
/* 绑定到一块内存空间 */ void automem_attach(automem_t* pmem, void* pdata, unsigned int len) { if(len > pmem->buffersize) automem_ensure_newspace(pmem, len - pmem->buffersize); pmem->size = len; memcpy(pmem->pdata, pdata, len); }
int automem_append_field_int(automem_t* pmem, const char * field, unsigned int f_len, int val) { char intVal[20];int slen; automem_append_voidp(pmem, field, f_len); _itoa(val, intVal,10); slen = strlen(intVal); automem_ensure_newspace(pmem, slen + 4); pmem->pdata[pmem->size++]='='; pmem->pdata[pmem->size++]='"'; automem_append_voidp(pmem, intVal, slen); pmem->pdata[pmem->size++]='"'; pmem->pdata[pmem->size++]=' '; return pmem->size; }
int automem_append_field_fast(automem_t* pmem, const char * field, unsigned int f_len, const char * val,unsigned int v_len) { if(NULL == val) return pmem->size; if(0 == v_len) v_len = strlen(val); if(0 == v_len) return pmem->size; automem_append_voidp(pmem, field, f_len); automem_ensure_newspace(pmem, v_len + 5); pmem->pdata[pmem->size++]='='; pmem->pdata[pmem->size++]='"'; automem_append_voidp(pmem, val, v_len); pmem->pdata[pmem->size++]='"'; pmem->pdata[pmem->size++]=' '; return pmem->size; }
/* 构造一个或者一堆的Frame 。 //服务器端发往客户端的数据 不允许使用 mask */ void wsframe_make(automem_t * mem,enum wsFrameType opcode, int _mask, unsigned char * payload, size_t len) { struct wsFrameHeader * fh; uint8_t mask[4]; size_t i; srand((unsigned int)time(NULL)); automem_ensure_newspace(mem, len + 20); fh = (struct wsFrameHeader * )(&mem->pdata[mem->size]); fh->fin = 1; fh->opcode = opcode; fh->rsv13 = 0; fh->mask = 0; mem->size += 2; if (len < 126) { fh->plen = (uint8_t)len; } else if (len <= 0xFFFF) { uint16_t nlen = SWAP_U16(len); fh->plen = 126; automem_append_voidp(mem, &nlen, 2); } else { uint64_t nlen = SWAP_U64(len); fh->plen = 127; automem_append_voidp(mem, &nlen, sizeof(uint64_t)); } if (payload && len > 0){ if (_mask) { fh->mask = 1; mask[0] = rand() % 256; mask[1] = rand() % 256; mask[2] = rand() % 256; mask[3] = rand() % 256; automem_append_voidp(mem, mask, 4); for (i = 0; i < len; i++) { mem->pdata[mem->size++] = payload[0] ^ mask[i % 4]; } } else { automem_append_voidp(mem, payload, len); } } }
void wsparser_pushdata(wsparser_t * parser, unsigned char * data, uint32_t size, wsparser_onhandler handler, void * eParam) { unsigned char *p = data; uint32_t i; if (parser->buf.size > 0) { automem_append_voidp(&parser->buf, data, size); data = parser->buf.pdata; size = parser->buf.size; } while (parser->offset < size) { switch (parser->st) { case WS_STATE_OPCODE: if (size - parser->offset > 2) { struct wsFrameHeader * fh = (struct wsFrameHeader *)&data[parser->offset]; parser->fin = fh->fin; parser->mask = fh->mask; parser->opcode = fh->opcode==WS_CONTINUATION_FRAME? parser->opcode: fh->opcode; parser->offset += 2; parser->st = WS_STATE_PLEN; printf("OpCode = %d, Fin=%d\n", parser->opcode,parser->fin); switch (fh->plen) { case 126: parser->st = WS_STATE_PLEN; break; case 127: parser->st = WS_STATE_PLLEN; break; default: parser->len = fh->plen; parser->st = parser->mask ? WS_STATE_MASK : WS_STATE_PAYLOAD; break; } if (WS_PING_FRAME == parser->opcode) { handler(parser, NULL, eParam); } } break; case WS_STATE_PLEN: if (size - parser->offset < 2) goto wsparser_pushdata_final; parser->len = SWAP_U16(*(uint16_t *)&data[parser->offset]); parser->offset += 2; parser->st = parser->mask ? WS_STATE_MASK : WS_STATE_PAYLOAD; break; case WS_STATE_PLLEN: if (size - parser->offset < 8) goto wsparser_pushdata_final; parser->len = SWAP_U64(*(uint64_t *)&data[parser->offset]); #if defined(_DEBUG) printf("size = %lld", parser->len); #endif parser->offset += 8; parser->st = parser->mask ? WS_STATE_MASK : WS_STATE_PAYLOAD; break; case WS_STATE_MASK: if (size - parser->offset < 4) goto wsparser_pushdata_final; memcpy(parser->msk_bytes, &data[parser->offset], 4); parser->offset += 4; parser->st = WS_STATE_PAYLOAD; break; case WS_STATE_PAYLOAD: if (size - parser->offset < parser->len) goto wsparser_pushdata_final; //处理帧数据 if (parser->mask) { automem_t * m = &parser->payload; automem_ensure_newspace(m, parser->len); for (i = 0; i < parser->len; i++) { m->pdata[m->size++] = data[parser->offset+i] ^ parser->msk_bytes[i % 4]; } } if (parser->fin == 1) { wsFrame * f = malloc(sizeof(wsFrame)); f->len = parser->payload.size; f->opcode = parser->opcode; f->pdata = f->len > 0 ? parser->payload.pdata : NULL; handler(parser, f, eParam); if (f->len){ parser->payload.pdata = NULL; parser->payload.size = parser->payload.buffersize = 0; automem_init(&parser->payload, 2048); } } parser->offset += (uint32_t)parser->len; parser->st = WS_STATE_OPCODE; break; } } wsparser_pushdata_final: if (size > parser->offset) { if (data != parser->buf.pdata) { automem_append_voidp(&parser->buf, data + parser->offset, size - parser->offset);//将未用完的加入到 buf. parser->offset = 0; } } else if (size <= parser->offset) { if (data == parser->buf.pdata) { } if (parser->buf.buffersize > parser->maxsize) automem_clean(&parser->buf, parser->maxsize); else automem_reset(&parser->buf); parser->offset = 0; } return; }
int automem_append_field(automem_t* pmem, const char * field, unsigned int f_len, const char * val) { const char * p = val; char c; unsigned int t = 4, sz = 0; if(NULL == val)return pmem->size; while(c = *p++) { switch(c) { case '&': // 5 & t+=5;break; case '<': // 4 < t+=4;break; case '>': // 4 > t+=4;break; case '"': // 6 " t+=6;break; case '\'': // 6 ' t+=6;break; default: t++; } } automem_append_voidp(pmem, field, f_len); automem_ensure_newspace(pmem, t); sz = pmem->size; pmem->pdata[sz++]='='; pmem->pdata[sz++]='"'; p = val; while(c = *p++) { switch(c) { case '&': // 5 & *(int*)(pmem->pdata+sz) = *(int*)"&"; sz+=sizeof(int); pmem->pdata[sz++]=';'; break; case '<': // 4 < *(int*)(pmem->pdata+sz) = *(int*)"<"; sz+=sizeof(int); break; case '>': // 4 > *(int*)(pmem->pdata+sz) = *(int*)">"; sz+=sizeof(int); break; case '"': // 6 " *(int*)(pmem->pdata+sz) = *(int*)"&quo"; sz+=sizeof(int); *(short*)(pmem->pdata+sz) = *(short*)"t;"; sz+=sizeof(short); break; case '\'': // 6 ' *(int*)(pmem->pdata+sz) = *(int*)"&apo"; sz+=sizeof(int); *(short*)(pmem->pdata+sz) = *(short*)"s;"; sz+=sizeof(short); break; default: pmem->pdata[sz++]=c; } } *(short*)(pmem->pdata+sz) = *(short*)"\" "; sz+=sizeof(short); pmem->size = sz; return sz; }