static HRESULT VBArray_ubound(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { VBArrayInstance *vbarray; int dim; HRESULT hres; TRACE("\n"); vbarray = vbarray_this(vthis); if(!vbarray) return throw_type_error(ctx, JS_E_VBARRAY_EXPECTED, NULL); if(argc) { hres = to_int32(ctx, argv[0], &dim); if(FAILED(hres)) return hres; } else dim = 1; hres = SafeArrayGetUBound(vbarray->safearray, dim, &dim); if(hres == DISP_E_BADINDEX) return throw_range_error(ctx, JS_E_SUBSCRIPT_OUT_OF_RANGE, NULL); else if(FAILED(hres)) return hres; if(r) *r = jsval_number(dim); return S_OK; }
/* ECMA-262 3rd Edition 9.6 */ HRESULT to_uint32(script_ctx_t *ctx, jsval_t val, DWORD *ret) { INT32 n; HRESULT hres; hres = to_int32(ctx, val, &n); if(SUCCEEDED(hres)) *ret = n; return hres; }
void print (std::ostream & stream) const { switch (get_type()) { case ValueType::Int32: stream << to_int32(); break; case ValueType::Utf8: stream << to_utf8(); break; default: stream << "?"; break; } }
static HRESULT Number_toPrecision(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { NumberInstance *number; INT prec = 0, size; jsstr_t *str; DOUBLE val; HRESULT hres; if(!(number = number_this(jsthis))) return throw_type_error(ctx, JS_E_NUMBER_EXPECTED, NULL); if(argc) { hres = to_int32(ctx, argv[0], &prec); if(FAILED(hres)) return hres; if(prec<1 || prec>21) return throw_range_error(ctx, JS_E_PRECISION_OUT_OF_RANGE, NULL); } val = number->value; if(isinf(val) || isnan(val) || !prec) { hres = to_string(ctx, jsval_number(val), &str); if(FAILED(hres)) return hres; } else { if(val != 0) size = floor(log10(val>0 ? val : -val)) + 1; else size = 1; if(size > prec) str = number_to_exponential(val, prec-1); else str = number_to_fixed(val, prec-size); if(!str) return E_OUTOFMEMORY; } if(r) *r = jsval_string(str); else jsstr_release(str); return S_OK; }
static HRESULT Number_toExponential(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { NumberInstance *number; DOUBLE val; INT prec = 0; jsstr_t *str; HRESULT hres; TRACE("\n"); if(!(number = number_this(jsthis))) return throw_type_error(ctx, JS_E_NUMBER_EXPECTED, NULL); if(argc) { hres = to_int32(ctx, argv[0], &prec); if(FAILED(hres)) return hres; if(prec<0 || prec>20) return throw_range_error(ctx, JS_E_FRACTION_DIGITS_OUT_OF_RANGE, NULL); } val = number->value; if(isinf(val) || isnan(val)) { hres = to_string(ctx, jsval_number(val), &str); if(FAILED(hres)) return hres; } else { if(!prec) prec--; str = number_to_exponential(val, prec); if(!str) return E_OUTOFMEMORY; } if(r) *r = jsval_string(str); else jsstr_release(str); return S_OK; }
static HRESULT VBArray_getItem(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { VBArrayInstance *vbarray; int i, *indexes; VARIANT out; HRESULT hres; TRACE("\n"); vbarray = vbarray_this(vthis); if(!vbarray) return throw_type_error(ctx, JS_E_VBARRAY_EXPECTED, NULL); if(argc < SafeArrayGetDim(vbarray->safearray)) return throw_range_error(ctx, JS_E_SUBSCRIPT_OUT_OF_RANGE, NULL); indexes = heap_alloc(sizeof(int)*argc); if(!indexes) return E_OUTOFMEMORY; for(i=0; i<argc; i++) { hres = to_int32(ctx, argv[i], indexes+i); if(FAILED(hres)) { heap_free(indexes); return hres; } } hres = SafeArrayGetElement(vbarray->safearray, indexes, (void*)&out); heap_free(indexes); if(hres == DISP_E_BADINDEX) return throw_range_error(ctx, JS_E_SUBSCRIPT_OUT_OF_RANGE, NULL); else if(FAILED(hres)) return hres; if(r) { hres = variant_to_jsval(&out, r); VariantClear(&out); } return hres; }
int ts::demuxer::demux_ts_packet(const char* ptr) { u_int32_t timecode=0; if(hdmv) { timecode=to_int32(ptr)&0x3fffffff; ptr+=4; } const char* end_ptr=ptr+188; if(ptr[0]!=0x47) // ts sync byte return -1; u_int16_t pid=to_int(ptr+1); u_int8_t flags=to_byte(ptr+3); bool transport_error=pid&0x8000; bool payload_unit_start_indicator=pid&0x4000; bool adaptation_field_exist=flags&0x20; bool payload_data_exist=flags&0x10; u_int8_t continuity_counter=flags&0x0f; pid&=0x1fff; if(transport_error) return -2; if(pid==0x1fff || !payload_data_exist) return 0; ptr+=4; // skip adaptation field if(adaptation_field_exist) { ptr+=to_byte(ptr)+1; if(ptr>=end_ptr) return -3; } #ifdef VERBOSE if(dump==1) printf("%.4x: [%c%c%c%c] %u.%i\n", pid, transport_error?'e':'-', payload_data_exist?'p':'-', payload_unit_start_indicator?'s':'-', adaptation_field_exist?'a':'-', timecode, continuity_counter ); #endif stream& s=streams[pid]; if(!pid || (s.channel!=0xffff && s.type==0xff)) { // PSI if(payload_unit_start_indicator) { // begin of PSI table ptr++; if(ptr>=end_ptr) return -4; if(*ptr!=0x00 && *ptr!=0x02) return 0; if(end_ptr-ptr<3) return -5; u_int16_t l=to_int(ptr+1); if((l&0x3000)!=0x3000) return -6; l&=0x0fff; ptr+=3; int len=end_ptr-ptr; if(l>len) { if(l>ts::table::max_buf_len) return -7; s.psi.reset(); memcpy(s.psi.buf,ptr,len); s.psi.offset+=len; s.psi.len=l; return 0; }else end_ptr=ptr+l; }else { // next part of PSI if(!s.psi.offset) return -8; int len=end_ptr-ptr; if(len>ts::table::max_buf_len-s.psi.offset) return -9; memcpy(s.psi.buf+s.psi.offset,ptr,len); s.psi.offset+=len; if(s.psi.offset<s.psi.len) return 0; else { ptr=s.psi.buf; end_ptr=ptr+s.psi.len; } } if(!pid) { // PAT ptr+=5; if(ptr>=end_ptr) return -10; int len=end_ptr-ptr-4; if(len<0 || len%4) return -11; int n=len/4; for(int i=0;i<n;i++,ptr+=4) { u_int16_t channel=to_int(ptr); u_int16_t pid=to_int(ptr+2); if((pid&0xe000)!=0xe000) return -12; pid&=0x1fff; if(!demuxer::channel || demuxer::channel==channel) { stream& ss=streams[pid]; ss.channel=channel; ss.type=0xff; } } }else { // PMT ptr+=7; if(ptr>=end_ptr) return -13; u_int16_t info_len=to_int(ptr)&0x0fff; ptr+=info_len+2; end_ptr-=4; if(ptr>=end_ptr) return -14; while(ptr<end_ptr) { if(end_ptr-ptr<5) return -15; u_int8_t type=to_byte(ptr); u_int16_t pid=to_int(ptr+1); if((pid&0xe000)!=0xe000) return -16; pid&=0x1fff; info_len=to_int(ptr+3)&0x0fff; ptr+=5+info_len; // ignore unknown streams if(validate_type(type)) { stream& ss=streams[pid]; if(ss.channel!=s.channel || ss.type!=type) { ss.channel=s.channel; ss.type=type; ss.id=++s.id; if(!parse_only && !ss.file.is_opened()) { if(dst.length()) { ss.file.open(file::out,"%s%c%s%s",dst.c_str(),os_slash,prefix.c_str(),get_stream_ext(get_stream_type(ss.type))); fprintf(stderr,"%s%c%s%s\n",dst.c_str(),os_slash,prefix.c_str(),get_stream_ext(get_stream_type(ss.type))); } else ss.file.open(file::out,"%s%s",prefix.c_str(),get_stream_ext(get_stream_type(ss.type))); } } } } if(ptr!=end_ptr) return -18; } }else { if(s.type!=0xff) { // PES if(payload_unit_start_indicator) { s.psi.reset(); s.psi.len=9; } while(s.psi.offset<s.psi.len) { int len=end_ptr-ptr; if(len<=0) return 0; int n=s.psi.len-s.psi.offset; if(len>n) len=n; memcpy(s.psi.buf+s.psi.offset,ptr,len); s.psi.offset+=len; ptr+=len; if(s.psi.len==9) s.psi.len+=to_byte(s.psi.buf+8); } if(s.psi.len) { if(memcmp(s.psi.buf,"\x00\x00\x01",3)) return -19; s.stream_id=to_byte(s.psi.buf+3); u_int8_t flags=to_byte(s.psi.buf+7); s.frame_num++; switch(flags&0xc0) { case 0x80: // PTS only { u_int64_t pts=decode_pts(s.psi.buf+9); #ifdef VERBOSE if(dump==2) printf("%.4x: %llu\n",pid,pts); else if(dump==3) printf("%.4x: track=%.4x.%.2i, type=%.2x, stream=%.2x, pts=%llums\n",pid,s.channel,s.id,s.type,s.stream_id,pts/90); #endif if(s.dts>0 && pts>s.dts) s.frame_length=(u_int32_t)(pts-s.dts); s.dts=pts; if(pts>s.last_pts) s.last_pts=pts; if(!s.first_pts) s.first_pts=pts; } break; case 0xc0: // PTS,DTS { u_int64_t pts=decode_pts(s.psi.buf+9); u_int64_t dts=decode_pts(s.psi.buf+14); #ifdef VERBOSE if(dump==2) printf("%.4x: %llu %llu\n",pid,pts,dts); else if(dump==3) printf("%.4x: track=%.4x.%.2i, type=%.2x, stream=%.2x, pts=%llums, dts=%llums\n",pid,s.channel,s.id,s.type,s.stream_id,pts/90,dts/90); #endif if(s.dts>0 && dts>s.dts) s.frame_length=(u_int32_t)(dts-s.dts); s.dts=dts; if(pts>s.last_pts) s.last_pts=pts; if(!s.first_dts) s.first_dts=dts; } break; } if(pes_output && s.file.is_opened()) s.file.write(s.psi.buf,s.psi.len); s.psi.reset(); } if(s.frame_num) { int len=end_ptr-ptr; if(es_parse) { switch(s.type) { case 0x1b: s.frame_num_h264.parse(ptr,len); break; case 0x06: case 0x81: case 0x83: s.frame_num_ac3.parse(ptr,len); break; } } if(s.file.is_opened()) s.file.write(ptr,len); } } } return 0; }
/* ECMA-262 3rd Edition 15.7.4.2 */ static HRESULT Number_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { NumberInstance *number; INT radix = 10; DOUBLE val; jsstr_t *str; HRESULT hres; TRACE("\n"); if(!(number = number_this(jsthis))) return throw_type_error(ctx, JS_E_NUMBER_EXPECTED, NULL); if(argc) { hres = to_int32(ctx, argv[0], &radix); if(FAILED(hres)) return hres; if(radix<2 || radix>36) return throw_type_error(ctx, JS_E_INVALIDARG, NULL); } val = number->value; if(radix==10 || isnan(val) || isinf(val)) { hres = to_string(ctx, jsval_number(val), &str); if(FAILED(hres)) return hres; } else { INT idx = 0; DOUBLE integ, frac, log_radix = 0; WCHAR buf[NUMBER_TOSTRING_BUF_SIZE+16]; BOOL exp = FALSE; if(val<0) { val = -val; buf[idx++] = '-'; } while(1) { integ = floor(val); frac = val-integ; if(integ == 0) buf[idx++] = '0'; while(integ>=1 && idx<NUMBER_TOSTRING_BUF_SIZE) { buf[idx] = fmod(integ, radix); if(buf[idx]<10) buf[idx] += '0'; else buf[idx] += 'a'-10; integ /= radix; idx++; } if(idx<NUMBER_TOSTRING_BUF_SIZE) { INT beg = buf[0]=='-'?1:0; INT end = idx-1; WCHAR wch; while(end > beg) { wch = buf[beg]; buf[beg++] = buf[end]; buf[end--] = wch; } } if(idx != NUMBER_TOSTRING_BUF_SIZE) buf[idx++] = '.'; while(frac>0 && idx<NUMBER_TOSTRING_BUF_SIZE) { frac *= radix; buf[idx] = fmod(frac, radix); frac -= buf[idx]; if(buf[idx]<10) buf[idx] += '0'; else buf[idx] += 'a'-10; idx++; } if(idx==NUMBER_TOSTRING_BUF_SIZE && !exp) { exp = TRUE; idx = (buf[0]=='-') ? 1 : 0; log_radix = floor(log(val)/log(radix)); val *= pow(radix, -log_radix); continue; } break; } while(buf[idx-1] == '0') idx--; if(buf[idx-1] == '.') idx--; if(exp) { if(log_radix==0) buf[idx] = 0; else { static const WCHAR formatW[] = {'(','e','%','c','%','d',')',0}; WCHAR ch; if(log_radix<0) { log_radix = -log_radix; ch = '-'; } else ch = '+'; sprintfW(&buf[idx], formatW, ch, (int)log_radix); } } else buf[idx] = '\0'; str = jsstr_alloc(buf); if(!str) return E_OUTOFMEMORY; } if(r) *r = jsval_string(str); else jsstr_release(str); return S_OK; }
/* ECMA-262 3rd Edition 15.7.4.2 */ static HRESULT Number_toString(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { NumberInstance *number; INT radix = 10; DOUBLE val; BSTR str; HRESULT hres; TRACE("\n"); if(!(number = number_this(jsthis))) return throw_type_error(ctx, ei, IDS_NOT_NUM, NULL); if(arg_cnt(dp)) { hres = to_int32(ctx, get_arg(dp, 0), ei, &radix); if(FAILED(hres)) return hres; if(radix<2 || radix>36) return throw_type_error(ctx, ei, IDS_INVALID_CALL_ARG, NULL); } if(V_VT(&number->num) == VT_I4) val = V_I4(&number->num); else val = V_R8(&number->num); if(radix==10 || isnan(val) || isinf(val)) { hres = to_string(ctx, &number->num, ei, &str); if(FAILED(hres)) return hres; } else { INT idx = 0; DOUBLE integ, frac, log_radix = 0; WCHAR buf[NUMBER_TOSTRING_BUF_SIZE+16]; BOOL exp = FALSE; if(val<0) { val = -val; buf[idx++] = '-'; } while(1) { integ = floor(val); frac = val-integ; if(integ == 0) buf[idx++] = '0'; while(integ>=1 && idx<NUMBER_TOSTRING_BUF_SIZE) { buf[idx] = fmod(integ, radix); if(buf[idx]<10) buf[idx] += '0'; else buf[idx] += 'a'-10; integ /= radix; idx++; } if(idx<NUMBER_TOSTRING_BUF_SIZE) { INT beg = buf[0]=='-'?1:0; INT end = idx-1; WCHAR wch; while(end > beg) { wch = buf[beg]; buf[beg++] = buf[end]; buf[end--] = wch; } } if(idx != NUMBER_TOSTRING_BUF_SIZE) buf[idx++] = '.'; while(frac>0 && idx<NUMBER_TOSTRING_BUF_SIZE) { frac *= radix; buf[idx] = fmod(frac, radix); frac -= buf[idx]; if(buf[idx]<10) buf[idx] += '0'; else buf[idx] += 'a'-10; idx++; } if(idx==NUMBER_TOSTRING_BUF_SIZE && !exp) { exp = TRUE; idx = (buf[0]=='-') ? 1 : 0; log_radix = floor(log(val)/log(radix)); val *= pow(radix, -log_radix); continue; } break; } while(buf[idx-1] == '0') idx--; if(buf[idx-1] == '.') idx--; if(exp) { if(log_radix==0) buf[idx++] = '\0'; else { static const WCHAR formatW[] = {'(','e','%','c','%','d',')',0}; WCHAR ch; if(log_radix<0) { log_radix = -log_radix; ch = '-'; } else ch = '+'; sprintfW(&buf[idx], formatW, ch, (int)log_radix); } } else buf[idx] = '\0'; str = SysAllocString(buf); if(!str) return E_OUTOFMEMORY; } if(retv) { V_VT(retv) = VT_BSTR; V_BSTR(retv) = str; }else { SysFreeString(str); } return S_OK; }
static inline boost::int32_t to_int32(const Byte *buf) { return to_int32(buf[0], buf[1], buf[2], buf[3]); }
static inline boost::int32_t to_int32(T1 high, T2 mid1, T3 mid2, T4 low) { return to_int32(static_cast<unsigned char>(high), static_cast<unsigned char>(mid1), static_cast<unsigned char>(mid2), static_cast<unsigned char>(low)); }
HRESULT variant_change_type(script_ctx_t *ctx, VARIANT *dst, VARIANT *src, VARTYPE vt) { jsval_t val; HRESULT hres; clear_ei(ctx); hres = variant_to_jsval(src, &val); if(FAILED(hres)) return hres; switch(vt) { case VT_I2: case VT_I4: { INT i; hres = to_int32(ctx, val, &i); if(SUCCEEDED(hres)) { if(vt == VT_I4) V_I4(dst) = i; else V_I2(dst) = i; } break; } case VT_R8: { double n; hres = to_number(ctx, val, &n); if(SUCCEEDED(hres)) V_R8(dst) = n; break; } case VT_R4: { double n; hres = to_number(ctx, val, &n); if(SUCCEEDED(hres)) V_R4(dst) = n; break; } case VT_BOOL: { BOOL b; hres = to_boolean(val, &b); if(SUCCEEDED(hres)) V_BOOL(dst) = b ? VARIANT_TRUE : VARIANT_FALSE; break; } case VT_BSTR: { jsstr_t *str; hres = to_string(ctx, val, &str); if(FAILED(hres)) break; if(str->length_flags & JSSTR_FLAG_NULLBSTR) { V_BSTR(dst) = NULL; break; } V_BSTR(dst) = SysAllocStringLen(str->str, jsstr_length(str)); if(!V_BSTR(dst)) hres = E_OUTOFMEMORY; break; } case VT_EMPTY: hres = V_VT(src) == VT_EMPTY ? S_OK : E_NOTIMPL; break; case VT_NULL: hres = V_VT(src) == VT_NULL ? S_OK : E_NOTIMPL; break; default: FIXME("vt %d not implemented\n", vt); hres = E_NOTIMPL; } jsval_release(val); if(FAILED(hres)) return hres; V_VT(dst) = vt; return S_OK; }