float StreamPeer::get_double() { uint8_t buf[8]; get_data(buf, 8); if (big_endian) { uint64_t *p64 = (uint64_t *)buf; *p64 = BSWAP64(*p64); } return decode_double(buf); }
int php_deserialize( rabbit * r, rawbuffer * buf, TValue * tv ) { if(!buf || !tv) { return -1; } setnilvalue(tv); int c = decode_read_byte( buf ); switch( c ) { case PHP_NULL: // kLOG(r, 0,"php decode nil\n"); return decode_null( r, buf, tv ); case PHP_INT: // kLOG(r, 0,"php decode int\n"); return decode_int( r, buf, tv ); case PHP_DOUBLE: // kLOG(r, 0,"php decode double\n"); return decode_double(r, buf, tv); case PHP_STRING: // kLOG(r, 0,"php decode string\n"); return decode_string(r, buf, tv); case PHP_ARRAY: // kLOG(r, 0,"php decode array\n"); return decode_array(r, buf, tv); case PHP_BOOL: return decode_bool(r, buf, tv); default: kLOG(r, 0, "php decode unknow:%c\n",c); break; } return -1; }
static gint gpm_render (GnomePrintContext *dest, const guchar *data, gint pos, gint len, gboolean pageops) { const guchar *end; data = data + pos; end = data + len; while (data < end){ gint32 opcode, i; guchar *cval; gint32 ival; gdouble dval; ArtBpath *bpath; data = decode_int (data, &opcode); switch ((GnomeMetaType) opcode) { case GNOME_META_BEGINPAGE: data = gpm_decode_string (data, &cval); if (pageops) gnome_print_beginpage (dest, cval); g_free (cval); break; case GNOME_META_SHOWPAGE: if (pageops) gnome_print_showpage (dest); break; case GNOME_META_GSAVE: gnome_print_gsave (dest); break; case GNOME_META_GRESTORE: gnome_print_grestore (dest); break; case GNOME_META_CLIP: data = gpm_decode_bpath (data, &bpath); data = decode_int (data, &ival); gnome_print_clip_bpath_rule (dest, bpath, ival); g_free (bpath); break; case GNOME_META_FILL: data = gpm_decode_bpath (data, &bpath); data = decode_int (data, &ival); gnome_print_fill_bpath_rule (dest, bpath, ival); g_free (bpath); break; case GNOME_META_STROKE: data = gpm_decode_bpath (data, &bpath); gnome_print_stroke_bpath (dest, bpath); g_free (bpath); break; case GNOME_META_IMAGE: { gdouble affine[6]; gint32 width, height, channels; guchar *buf; data = decode_double (data, &affine[0]); data = decode_double (data, &affine[1]); data = decode_double (data, &affine[2]); data = decode_double (data, &affine[3]); data = decode_double (data, &affine[4]); data = decode_double (data, &affine[5]); data = decode_int (data, &height); data = decode_int (data, &width); data = decode_int (data, &channels); buf = g_new (guchar, height * width * channels); memcpy (buf, data, height * width * channels); data += height * width * channels; gnome_print_image_transform (dest, affine, buf, width, height, channels * width, channels); g_free (buf); break; } case GNOME_META_GLYPHLIST: { GnomeGlyphList *gl; gdouble affine[6]; gint32 len, code, ival, i; gdouble dval; data = decode_double (data, &affine[0]); data = decode_double (data, &affine[1]); data = decode_double (data, &affine[2]); data = decode_double (data, &affine[3]); data = decode_double (data, &affine[4]); data = decode_double (data, &affine[5]); gl = gnome_glyphlist_new (); data = decode_int (data, &len); if (len > 0) { gl->glyphs = g_new (int, len); gl->g_length = len; gl->g_size = len; for (i = 0; i < len; i++) { data = decode_int (data, &ival); gl->glyphs[i] = ival; } } data = decode_int (data, &len); if (len > 0) { gl->rules = g_new (GGLRule, len); gl->r_length = len; gl->r_size = len; for (i = 0; i < len; i++) { data = decode_int (data, &code); gl->rules[i].code = code; switch (code) { case GGL_POSITION: case GGL_ADVANCE: case GGL_COLOR: data = decode_int (data, &ival); gl->rules[i].value.ival = ival; break; case GGL_MOVETOX: case GGL_MOVETOY: case GGL_RMOVETOX: case GGL_RMOVETOY: case GGL_LETTERSPACE: case GGL_KERNING: data = decode_double (data, &dval); gl->rules[i].value.dval = dval; break; case GGL_FONT: { GnomeFont *font; guchar *name; data = decode_double (data, &dval); data = gpm_decode_string (data, &name); font = gnome_font_find (name, dval); if (font == NULL) g_warning ("Cannot find font: %s\n", name); g_free (name); gl->rules[i].value.font = font; break; } default: break; } } } gnome_print_glyphlist_transform (dest, affine, gl); gnome_glyphlist_unref (gl); break; } break; case GNOME_META_COLOR: { gdouble r, g, b, a; data = decode_double (data, &r); data = decode_double (data, &g); data = decode_double (data, &b); gnome_print_setrgbcolor (dest, r, g, b); data = decode_double (data, &a); gnome_print_setopacity (dest, a); break; } case GNOME_META_LINE: data = decode_double (data, &dval); gnome_print_setlinewidth (dest, dval); data = decode_double (data, &dval); gnome_print_setmiterlimit (dest, dval); data = decode_int (data, &ival); gnome_print_setlinejoin (dest, ival); data = decode_int (data, &ival); gnome_print_setlinecap (dest, ival); break; case GNOME_META_DASH: { int n; double *values, offset; data = decode_int (data, &n); values = g_new (double, n); for (i = 0; i < n; i++) { data = decode_double (data, &values [i]); } data = decode_double (data, &offset); gnome_print_setdash (dest, n, values, offset); g_free (values); break; } default: g_warning ("Serious print meta data corruption %d", opcode); break; } }
Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len) { const uint8_t *buf = p_buffer; int len = p_len; if (len < 4) { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); } uint32_t type = decode_uint32(buf); ERR_FAIL_COND_V((type & ENCODE_MASK) >= Variant::VARIANT_MAX, ERR_INVALID_DATA); buf += 4; len -= 4; if (r_len) *r_len = 4; switch (type & ENCODE_MASK) { case Variant::NIL: { r_variant = Variant(); } break; case Variant::BOOL: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); bool val = decode_uint32(buf); r_variant = val; if (r_len) (*r_len) += 4; } break; case Variant::INT: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); if (type & ENCODE_FLAG_64) { int64_t val = decode_uint64(buf); r_variant = val; if (r_len) (*r_len) += 8; } else { int32_t val = decode_uint32(buf); r_variant = val; if (r_len) (*r_len) += 4; } } break; case Variant::REAL: { ERR_FAIL_COND_V(len < (int)4, ERR_INVALID_DATA); if (type & ENCODE_FLAG_64) { double val = decode_double(buf); r_variant = val; if (r_len) (*r_len) += 8; } else { float val = decode_float(buf); r_variant = val; if (r_len) (*r_len) += 4; } } break; case Variant::STRING: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); uint32_t strlen = decode_uint32(buf); buf += 4; len -= 4; ERR_FAIL_COND_V((int)strlen > len, ERR_INVALID_DATA); String str; str.parse_utf8((const char *)buf, strlen); r_variant = str; if (r_len) { if (strlen % 4) (*r_len) += 4 - strlen % 4; (*r_len) += 4 + strlen; } } break; // math types case Variant::VECTOR2: { ERR_FAIL_COND_V(len < (int)4 * 2, ERR_INVALID_DATA); Vector2 val; val.x = decode_float(&buf[0]); val.y = decode_float(&buf[4]); r_variant = val; if (r_len) (*r_len) += 4 * 2; } break; // 5 case Variant::RECT2: { ERR_FAIL_COND_V(len < (int)4 * 4, ERR_INVALID_DATA); Rect2 val; val.position.x = decode_float(&buf[0]); val.position.y = decode_float(&buf[4]); val.size.x = decode_float(&buf[8]); val.size.y = decode_float(&buf[12]); r_variant = val; if (r_len) (*r_len) += 4 * 4; } break; case Variant::VECTOR3: { ERR_FAIL_COND_V(len < (int)4 * 3, ERR_INVALID_DATA); Vector3 val; val.x = decode_float(&buf[0]); val.y = decode_float(&buf[4]); val.z = decode_float(&buf[8]); r_variant = val; if (r_len) (*r_len) += 4 * 3; } break; case Variant::TRANSFORM2D: { ERR_FAIL_COND_V(len < (int)4 * 6, ERR_INVALID_DATA); Transform2D val; for (int i = 0; i < 3; i++) { for (int j = 0; j < 2; j++) { val.elements[i][j] = decode_float(&buf[(i * 2 + j) * 4]); } } r_variant = val; if (r_len) (*r_len) += 4 * 6; } break; case Variant::PLANE: { ERR_FAIL_COND_V(len < (int)4 * 4, ERR_INVALID_DATA); Plane val; val.normal.x = decode_float(&buf[0]); val.normal.y = decode_float(&buf[4]); val.normal.z = decode_float(&buf[8]); val.d = decode_float(&buf[12]); r_variant = val; if (r_len) (*r_len) += 4 * 4; } break; case Variant::QUAT: { ERR_FAIL_COND_V(len < (int)4 * 4, ERR_INVALID_DATA); Quat val; val.x = decode_float(&buf[0]); val.y = decode_float(&buf[4]); val.z = decode_float(&buf[8]); val.w = decode_float(&buf[12]); r_variant = val; if (r_len) (*r_len) += 4 * 4; } break; case Variant::RECT3: { ERR_FAIL_COND_V(len < (int)4 * 6, ERR_INVALID_DATA); Rect3 val; val.position.x = decode_float(&buf[0]); val.position.y = decode_float(&buf[4]); val.position.z = decode_float(&buf[8]); val.size.x = decode_float(&buf[12]); val.size.y = decode_float(&buf[16]); val.size.z = decode_float(&buf[20]); r_variant = val; if (r_len) (*r_len) += 4 * 6; } break; case Variant::BASIS: { ERR_FAIL_COND_V(len < (int)4 * 9, ERR_INVALID_DATA); Basis val; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { val.elements[i][j] = decode_float(&buf[(i * 3 + j) * 4]); } } r_variant = val; if (r_len) (*r_len) += 4 * 9; } break; case Variant::TRANSFORM: { ERR_FAIL_COND_V(len < (int)4 * 12, ERR_INVALID_DATA); Transform val; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { val.basis.elements[i][j] = decode_float(&buf[(i * 3 + j) * 4]); } } val.origin[0] = decode_float(&buf[36]); val.origin[1] = decode_float(&buf[40]); val.origin[2] = decode_float(&buf[44]); r_variant = val; if (r_len) (*r_len) += 4 * 12; } break; // misc types case Variant::COLOR: { ERR_FAIL_COND_V(len < (int)4 * 4, ERR_INVALID_DATA); Color val; val.r = decode_float(&buf[0]); val.g = decode_float(&buf[4]); val.b = decode_float(&buf[8]); val.a = decode_float(&buf[12]); r_variant = val; if (r_len) (*r_len) += 4 * 4; } break; case Variant::NODE_PATH: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); uint32_t strlen = decode_uint32(buf); if (strlen & 0x80000000) { //new format ERR_FAIL_COND_V(len < 12, ERR_INVALID_DATA); Vector<StringName> names; Vector<StringName> subnames; StringName prop; uint32_t namecount = strlen &= 0x7FFFFFFF; uint32_t subnamecount = decode_uint32(buf + 4); uint32_t flags = decode_uint32(buf + 8); len -= 12; buf += 12; int total = namecount + subnamecount; if (flags & 2) total++; if (r_len) (*r_len) += 12; for (int i = 0; i < total; i++) { ERR_FAIL_COND_V((int)len < 4, ERR_INVALID_DATA); strlen = decode_uint32(buf); int pad = 0; if (strlen % 4) pad += 4 - strlen % 4; buf += 4; len -= 4; ERR_FAIL_COND_V((int)strlen + pad > len, ERR_INVALID_DATA); String str; str.parse_utf8((const char *)buf, strlen); if (i < namecount) names.push_back(str); else if (i < namecount + subnamecount) subnames.push_back(str); else prop = str; buf += strlen + pad; len -= strlen + pad; if (r_len) (*r_len) += 4 + strlen + pad; } r_variant = NodePath(names, subnames, flags & 1, prop); } else { //old format, just a string buf += 4; len -= 4; ERR_FAIL_COND_V((int)strlen > len, ERR_INVALID_DATA); String str; str.parse_utf8((const char *)buf, strlen); r_variant = NodePath(str); if (r_len) (*r_len) += 4 + strlen; } } break; /*case Variant::RESOURCE: { ERR_EXPLAIN("Can't marshallize resources"); ERR_FAIL_V(ERR_INVALID_DATA); //no, i'm sorry, no go } break;*/ case Variant::_RID: { r_variant = RID(); } break; case Variant::OBJECT: { r_variant = (Object *)NULL; } break; case Variant::DICTIONARY: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); uint32_t count = decode_uint32(buf); // bool shared = count&0x80000000; count &= 0x7FFFFFFF; buf += 4; len -= 4; if (r_len) { (*r_len) += 4; } Dictionary d; for (uint32_t i = 0; i < count; i++) { Variant key, value; int used; Error err = decode_variant(key, buf, len, &used); ERR_FAIL_COND_V(err, err); buf += used; len -= used; if (r_len) { (*r_len) += used; } err = decode_variant(value, buf, len, &used); ERR_FAIL_COND_V(err, err); buf += used; len -= used; if (r_len) { (*r_len) += used; } d[key] = value; } r_variant = d; } break; case Variant::ARRAY: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); uint32_t count = decode_uint32(buf); // bool shared = count&0x80000000; count &= 0x7FFFFFFF; buf += 4; len -= 4; if (r_len) { (*r_len) += 4; } Array varr; for (uint32_t i = 0; i < count; i++) { int used = 0; Variant v; Error err = decode_variant(v, buf, len, &used); ERR_FAIL_COND_V(err, err); buf += used; len -= used; varr.push_back(v); if (r_len) { (*r_len) += used; } } r_variant = varr; } break; // arrays case Variant::POOL_BYTE_ARRAY: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); uint32_t count = decode_uint32(buf); buf += 4; len -= 4; ERR_FAIL_COND_V((int)count > len, ERR_INVALID_DATA); PoolVector<uint8_t> data; if (count) { data.resize(count); PoolVector<uint8_t>::Write w = data.write(); for (int i = 0; i < count; i++) { w[i] = buf[i]; } w = PoolVector<uint8_t>::Write(); } r_variant = data; if (r_len) { if (count % 4) (*r_len) += 4 - count % 4; (*r_len) += 4 + count; } } break; case Variant::POOL_INT_ARRAY: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); uint32_t count = decode_uint32(buf); buf += 4; len -= 4; ERR_FAIL_COND_V((int)count * 4 > len, ERR_INVALID_DATA); PoolVector<int> data; if (count) { //const int*rbuf=(const int*)buf; data.resize(count); PoolVector<int>::Write w = data.write(); for (int i = 0; i < count; i++) { w[i] = decode_uint32(&buf[i * 4]); } w = PoolVector<int>::Write(); } r_variant = Variant(data); if (r_len) { (*r_len) += 4 + count * sizeof(int); } } break; case Variant::POOL_REAL_ARRAY: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); uint32_t count = decode_uint32(buf); buf += 4; len -= 4; ERR_FAIL_COND_V((int)count * 4 > len, ERR_INVALID_DATA); PoolVector<float> data; if (count) { //const float*rbuf=(const float*)buf; data.resize(count); PoolVector<float>::Write w = data.write(); for (int i = 0; i < count; i++) { w[i] = decode_float(&buf[i * 4]); } w = PoolVector<float>::Write(); } r_variant = data; if (r_len) { (*r_len) += 4 + count * sizeof(float); } } break; case Variant::POOL_STRING_ARRAY: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); uint32_t count = decode_uint32(buf); PoolVector<String> strings; buf += 4; len -= 4; if (r_len) (*r_len) += 4; //printf("string count: %i\n",count); for (int i = 0; i < (int)count; i++) { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); uint32_t strlen = decode_uint32(buf); buf += 4; len -= 4; ERR_FAIL_COND_V((int)strlen > len, ERR_INVALID_DATA); //printf("loaded string: %s\n",(const char*)buf); String str; str.parse_utf8((const char *)buf, strlen); strings.push_back(str); buf += strlen; len -= strlen; if (r_len) (*r_len) += 4 + strlen; if (strlen % 4) { int pad = 4 - (strlen % 4); buf += pad; len -= pad; if (r_len) { (*r_len) += pad; } } } r_variant = strings; } break; case Variant::POOL_VECTOR2_ARRAY: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); uint32_t count = decode_uint32(buf); buf += 4; len -= 4; ERR_FAIL_COND_V((int)count * 4 * 2 > len, ERR_INVALID_DATA); PoolVector<Vector2> varray; if (r_len) { (*r_len) += 4; } if (count) { varray.resize(count); PoolVector<Vector2>::Write w = varray.write(); for (int i = 0; i < (int)count; i++) { w[i].x = decode_float(buf + i * 4 * 2 + 4 * 0); w[i].y = decode_float(buf + i * 4 * 2 + 4 * 1); } int adv = 4 * 2 * count; if (r_len) (*r_len) += adv; len -= adv; buf += adv; } r_variant = varray; } break; case Variant::POOL_VECTOR3_ARRAY: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); uint32_t count = decode_uint32(buf); buf += 4; len -= 4; ERR_FAIL_COND_V((int)count * 4 * 3 > len, ERR_INVALID_DATA); PoolVector<Vector3> varray; if (r_len) { (*r_len) += 4; } if (count) { varray.resize(count); PoolVector<Vector3>::Write w = varray.write(); for (int i = 0; i < (int)count; i++) { w[i].x = decode_float(buf + i * 4 * 3 + 4 * 0); w[i].y = decode_float(buf + i * 4 * 3 + 4 * 1); w[i].z = decode_float(buf + i * 4 * 3 + 4 * 2); } int adv = 4 * 3 * count; if (r_len) (*r_len) += adv; len -= adv; buf += adv; } r_variant = varray; } break; case Variant::POOL_COLOR_ARRAY: { ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA); uint32_t count = decode_uint32(buf); buf += 4; len -= 4; ERR_FAIL_COND_V((int)count * 4 * 4 > len, ERR_INVALID_DATA); PoolVector<Color> carray; if (r_len) { (*r_len) += 4; } if (count) { carray.resize(count); PoolVector<Color>::Write w = carray.write(); for (int i = 0; i < (int)count; i++) { w[i].r = decode_float(buf + i * 4 * 4 + 4 * 0); w[i].g = decode_float(buf + i * 4 * 4 + 4 * 1); w[i].b = decode_float(buf + i * 4 * 4 + 4 * 2); w[i].a = decode_float(buf + i * 4 * 4 + 4 * 3); } int adv = 4 * 4 * count; if (r_len) (*r_len) += adv; len -= adv; buf += adv; } r_variant = carray; } break; default: { ERR_FAIL_V(ERR_BUG); } } return OK; }
void decode_cell(pTHX_ unsigned char *input, STRLEN len, STRLEN *pos, struct cc_type *type, SV *output) { unsigned char *bytes; STRLEN bytes_len; if (unpack_bytes(aTHX_ input, len, pos, &bytes, &bytes_len) != 0) { sv_setsv(output, &PL_sv_undef); return; } switch (type->type_id) { case CC_TYPE_ASCII: case CC_TYPE_CUSTOM: case CC_TYPE_BLOB: decode_blob(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_BOOLEAN: decode_boolean(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_VARCHAR: case CC_TYPE_TEXT: decode_utf8(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_INET: decode_inet(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_SET: case CC_TYPE_LIST: decode_list(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_UUID: case CC_TYPE_TIMEUUID: decode_uuid(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_FLOAT: decode_float(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_DOUBLE: decode_double(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_DECIMAL: decode_decimal(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_VARINT: case CC_TYPE_BIGINT: case CC_TYPE_COUNTER: case CC_TYPE_TIMESTAMP: case CC_TYPE_SMALLINT: case CC_TYPE_TINYINT: case CC_TYPE_INT: decode_varint(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_DATE: decode_date(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_TIME: decode_time(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_MAP: decode_map(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_UDT: decode_udt(aTHX_ bytes, bytes_len, type, output); break; case CC_TYPE_TUPLE: decode_tuple(aTHX_ bytes, bytes_len, type, output); break; default: sv_setsv(output, &PL_sv_undef); warn("Decoder doesn't yet understand type %d, returning undef instead", type->type_id); break; } }