JSObject * SavedStacks::getOrCreateSavedFramePrototype(JSContext *cx) { if (savedFrameProto) return savedFrameProto; Rooted<GlobalObject *> global(cx, cx->compartment()->maybeGlobal()); if (!global) return nullptr; RootedObject proto(cx, NewObjectWithGivenProto(cx, &SavedFrame::class_, global->getOrCreateObjectPrototype(cx), global)); if (!proto || !JS_DefineProperties(cx, proto, SavedFrame::properties) || !JS_DefineFunctions(cx, proto, SavedFrame::methods) || !JSObject::freeze(cx, proto)) return nullptr; savedFrameProto = proto; // The only object with the SavedFrame::class_ that doesn't have a source // should be the prototype. savedFrameProto->setReservedSlot(SavedFrame::JSSLOT_SOURCE, NullValue()); return savedFrameProto; }
bool ValueImpl::getBool() const { if (null) throw NullValue(); return !data.empty() && isTrue(data.at(0)); }
Decimal getDecimal(const MYSQL_BIND& bind) { if (isNull(bind)) throw NullValue(); switch (bind.buffer_type) { case MYSQL_TYPE_TINY: case MYSQL_TYPE_SHORT: case MYSQL_TYPE_INT24: case MYSQL_TYPE_LONG: case MYSQL_TYPE_LONGLONG: { int64_t i = getInteger<int64_t>(bind); Decimal d(i); return d; } case MYSQL_TYPE_FLOAT: case MYSQL_TYPE_DOUBLE: { double f = getFloat<double>(bind); Decimal d(f); return d; } case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_NEWDECIMAL: case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_STRING: { std::string data(static_cast<char*>(bind.buffer), *bind.length); log_debug("extract Decimal from string \"" << data << '"'); std::istringstream in(data); Decimal ret; in >> ret; if (in.eof() || !in.fail()) return ret; // no break!!! } default: log_error("type-error in getDecimal, type=" << bind.buffer_type); throw TypeError("type-error in getDecimal"); } }
JSObject * SavedStacks::getOrCreateSavedFramePrototype(JSContext *cx) { if (savedFrameProto) return savedFrameProto; Rooted<GlobalObject *> global(cx, cx->compartment()->maybeGlobal()); if (!global) return nullptr; savedFrameProto = js_InitClass(cx, global, global->getOrCreateObjectPrototype(cx), &SavedFrame::class_, SavedFrame::construct, 0, SavedFrame::properties, SavedFrame::methods, nullptr, nullptr); // The only object with the SavedFrame::class_ that doesn't have a source // should be the prototype. savedFrameProto->setReservedSlot(SavedFrame::JSSLOT_SOURCE, NullValue()); return savedFrameProto; }
Date getDate(const MYSQL_BIND& bind) { if (isNull(bind)) throw NullValue(); switch (bind.buffer_type) { case MYSQL_TYPE_DATE: case MYSQL_TYPE_DATETIME: case MYSQL_TYPE_TIMESTAMP: { MYSQL_TIME* ts = static_cast<MYSQL_TIME*>(bind.buffer); return Date(ts->year, ts->month, ts->day); } default: log_error("type-error in getDate, type=" << bind.buffer_type); throw TypeError("type-error in getDate"); } }
Time getTime(const MYSQL_BIND& bind) { if (isNull(bind)) throw NullValue(); switch (bind.buffer_type) { case MYSQL_TYPE_TIME: case MYSQL_TYPE_DATETIME: case MYSQL_TYPE_TIMESTAMP: { MYSQL_TIME* ts = static_cast<MYSQL_TIME*>(bind.buffer); return Time(ts->hour, ts->minute, ts->second); } default: log_error("type-error in getTime, type=" << bind.buffer_type); throw TypeError("type-error in getTime"); } }
void SavedFrame::initFromLookup(Lookup &lookup) { JS_ASSERT(lookup.source); JS_ASSERT(getReservedSlot(JSSLOT_SOURCE).isUndefined()); setReservedSlot(JSSLOT_SOURCE, StringValue(lookup.source)); setReservedSlot(JSSLOT_LINE, NumberValue(lookup.line)); setReservedSlot(JSSLOT_COLUMN, NumberValue(lookup.column)); setReservedSlot(JSSLOT_FUNCTIONDISPLAYNAME, lookup.functionDisplayName ? StringValue(lookup.functionDisplayName) : NullValue()); setReservedSlot(JSSLOT_PARENT, ObjectOrNullValue(lookup.parent)); setReservedSlot(JSSLOT_PRIVATE_PARENT, PrivateValue(lookup.parent)); JS_ASSERT(getReservedSlot(JSSLOT_PRINCIPALS).isUndefined()); if (lookup.principals) JS_HoldPrincipals(lookup.principals); setReservedSlot(JSSLOT_PRINCIPALS, PrivateValue(lookup.principals)); }
void getBlob(const MYSQL_BIND& bind, Blob& ret) { if (isNull(bind)) throw NullValue(); switch (bind.buffer_type) { case MYSQL_TYPE_STRING: case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_BLOB: case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_LONG_BLOB: ret.assign(static_cast<const char*>(bind.buffer), *bind.length); break; default: log_error("type-error in getBlob, type=" << bind.buffer_type); throw TypeError("type-error in getBlob"); } }
float_type getFloat(const MYSQL_BIND& bind) { if (isNull(bind)) throw NullValue(); switch (bind.buffer_type) { case MYSQL_TYPE_TINY: case MYSQL_TYPE_SHORT: case MYSQL_TYPE_INT24: case MYSQL_TYPE_LONG: return getInteger<int>(bind); case MYSQL_TYPE_FLOAT: return *static_cast<float*>(bind.buffer); case MYSQL_TYPE_DOUBLE: return *static_cast<double*>(bind.buffer); case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_STRING: { std::string data(static_cast<char*>(bind.buffer), *bind.length); log_debug("extract float-type from string \"" << data << '"'); std::istringstream in(data); float_type ret; in >> ret; if (in.eof() || !in.fail()) return ret; // no break!!! } default: log_error("type-error in getFloat, type=" << bind.buffer_type); throw TypeError("type-error in getFloat"); } }
char getChar(const MYSQL_BIND& bind) { if (isNull(bind)) throw NullValue(); switch (bind.buffer_type) { case MYSQL_TYPE_TINY: if (bind.is_unsigned) return *static_cast<unsigned char*>(bind.buffer); else return *static_cast<signed char*>(bind.buffer); case MYSQL_TYPE_STRING: case MYSQL_TYPE_VAR_STRING: if (*bind.length > 0) return *static_cast<char*>(bind.buffer); // no break! default: log_error("type-error in getChar, type=" << bind.buffer_type); throw TypeError("type-error in getChar"); } }
void ValueImpl::getBlob(Blob& ret) const { if (null) throw NullValue(); ret.assign(data.data(), data.size()); }
Datetime ValueImpl::getDatetime() const { if (null) throw NullValue(); return Datetime::fromIso(data); }
char ValueImpl::getChar() const { if (null) throw NullValue(); return data.at(0); }
void ValueImpl::getString(std::string& ret) const { if (null) throw NullValue(); ret.assign(data); }
float ValueImpl::getFloat() const { if (null) throw NullValue(); return getValue<float>(data, "float"); }
double ValueImpl::getDouble() const { if (null) throw NullValue(); return getValue<double>(data, "double"); }
uint64_t ValueImpl::getUnsigned64() const { if (null) throw NullValue(); return getValue<uint64_t>(data, "uint64_t"); }
Decimal ValueImpl::getDecimal() const { if (null) throw NullValue(); return getValue<Decimal>(data, "Decimal"); }
int_type getInteger(const MYSQL_BIND& bind) { if (isNull(bind)) throw NullValue(); switch (bind.buffer_type) { case MYSQL_TYPE_TINY: if (bind.is_unsigned) return *static_cast<unsigned char*>(bind.buffer); else return *static_cast<signed char*>(bind.buffer); case MYSQL_TYPE_SHORT: if (bind.is_unsigned) return *static_cast<unsigned short int*>(bind.buffer); else return *static_cast<short int*>(bind.buffer); case MYSQL_TYPE_INT24: { unsigned char* ptr = reinterpret_cast<unsigned char*>(bind.buffer); if (bind.is_unsigned) { #if __BYTE_ORDER == __LITTLE_ENDIAN return (static_cast<int_type>(ptr[0])) + (static_cast<int_type>(ptr[1]) << 8) + (static_cast<int_type>(ptr[2]) << 16); #else return (static_cast<int_type>(ptr[2])) + (static_cast<int_type>(ptr[1]) << 8) + (static_cast<int_type>(ptr[0]) << 16); #endif } else { #if __BYTE_ORDER == __LITTLE_ENDIAN if (ptr[2] < 128) { return static_cast<int_type>(ptr[0]) + (static_cast<int_type>(ptr[1]) << 8) + (static_cast<int_type>(ptr[2]) << 16); } else { int32_t val; unsigned char* vptr = reinterpret_cast<unsigned char*>(&val); vptr[0] = ptr[0]; vptr[1] = ptr[1]; vptr[2] = ptr[2]; vptr[3] = '\xff'; return static_cast<int_type>(val); } #else if (ptr[2] < 128) { return (static_cast<int_type>(ptr[2])) + (static_cast<int_type>(ptr[1]) << 8) + (static_cast<int_type>(ptr[0]) << 16); } else { int32_t val; unsigned char* vptr = reinterpret_cast<unsigned char*>(&val); vptr[0] = '\xff'; vptr[1] = ptr[0]; vptr[2] = ptr[1]; vptr[3] = ptr[2]; return static_cast<int_type>(val); } #endif } } case MYSQL_TYPE_LONG: if (bind.is_unsigned) return *static_cast<unsigned int*>(bind.buffer); else return *static_cast<int*>(bind.buffer); case MYSQL_TYPE_LONGLONG: if (bind.is_unsigned) return *static_cast<long long unsigned*>(bind.buffer); else return *static_cast<long long int*>(bind.buffer); case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_NEWDECIMAL: { std::string data(static_cast<char*>(bind.buffer), *bind.length); log_debug("extract integer-type from decimal \"" << data << '"'); std::istringstream in(data); Decimal decimal; decimal.read(in); if (in.eof() || !in.fail()) { int_type ret = decimal.getInteger<int_type>(); return ret; } log_error("type-error in getInteger, type=" << bind.buffer_type); throw TypeError("type-error in getInteger"); } case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_STRING: { std::string data(static_cast<char*>(bind.buffer), *bind.length); log_debug("extract integer-type from string \"" << data << '"'); std::istringstream in(data); int_type ret; in >> ret; if (in.eof() || !in.fail()) return ret; // no break!!! } default: log_error("type-error in getInteger, type=" << bind.buffer_type); throw TypeError("type-error in getInteger"); } }
long ValueImpl::getLong() const { if (null) throw NullValue(); return getValue<long>(data, "long"); }
short ValueImpl::getShort() const { if (null) throw NullValue(); return getValue<short>(data, "short"); }
void Document::read(BinaryReader& reader) { int size; reader >> size; unsigned char type; reader >> type; while (type != '\0') { Element::Ptr element; std::string name = BSONReader(reader).readCString(); switch (type) { case ElementTraits<double>::TypeId: element = new ConcreteElement<double>(name, 0); break; case ElementTraits<Int32>::TypeId: element = new ConcreteElement<Int32>(name, 0); break; case ElementTraits<std::string>::TypeId: element = new ConcreteElement<std::string>(name, ""); break; case ElementTraits<Document::Ptr>::TypeId: element = new ConcreteElement<Document::Ptr>(name, new Document); break; case ElementTraits<Array::Ptr>::TypeId: element = new ConcreteElement<Array::Ptr>(name, new Array); break; case ElementTraits<Binary::Ptr>::TypeId: element = new ConcreteElement<Binary::Ptr>(name, new Binary); break; case ElementTraits<ObjectId::Ptr>::TypeId: element = new ConcreteElement<ObjectId::Ptr>(name, new ObjectId); break; case ElementTraits<bool>::TypeId: element = new ConcreteElement<bool>(name, false); break; case ElementTraits<Poco::Timestamp>::TypeId: element = new ConcreteElement<Poco::Timestamp>(name, Poco::Timestamp()); break; case ElementTraits<BSONTimestamp>::TypeId: element = new ConcreteElement<BSONTimestamp>(name, BSONTimestamp()); break; case ElementTraits<NullValue>::TypeId: element = new ConcreteElement<NullValue>(name, NullValue(0)); break; case ElementTraits<RegularExpression::Ptr>::TypeId: element = new ConcreteElement<RegularExpression::Ptr>(name, new RegularExpression()); break; case ElementTraits<JavaScriptCode::Ptr>::TypeId: element = new ConcreteElement<JavaScriptCode::Ptr>(name, new JavaScriptCode()); break; case ElementTraits<Int64>::TypeId: element = new ConcreteElement<Int64>(name, 0); break; default: { std::stringstream ss; ss << "Element " << name << " contains an unsupported type 0x" << std::hex << (int) type; throw Poco::NotImplementedException(ss.str()); } //TODO: x0F -> JavaScript code with scope // xFF -> Min Key // x7F -> Max Key } element->read(reader); _elements.push_back(element); reader >> type; } }
void getString(const MYSQL_BIND& bind, std::string& ret) { if (isNull(bind)) throw NullValue(); switch (bind.buffer_type) { case MYSQL_TYPE_STRING: case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_BLOB: case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_NEWDECIMAL: ret.assign(static_cast<const char*>(bind.buffer), *bind.length); break; case MYSQL_TYPE_DATE: { MYSQL_TIME* ts = static_cast<MYSQL_TIME*>(bind.buffer); ret.assign(Date(ts->year, ts->month, ts->day).getIso()); break; } case MYSQL_TYPE_TIME: { MYSQL_TIME* ts = static_cast<MYSQL_TIME*>(bind.buffer); ret.assign(Time(ts->hour, ts->minute, ts->second).getIso()); break; } case MYSQL_TYPE_DATETIME: case MYSQL_TYPE_TIMESTAMP: { MYSQL_TIME* ts = static_cast<MYSQL_TIME*>(bind.buffer); ret.assign(Datetime(ts->year, ts->month, ts->day, ts->hour, ts->minute, ts->second, ts->second_part).getIso()); break; } default: { std::ostringstream s; switch (bind.buffer_type) { case MYSQL_TYPE_TINY: case MYSQL_TYPE_SHORT: case MYSQL_TYPE_INT24: case MYSQL_TYPE_LONG: if (bind.is_unsigned) s << getInteger<unsigned int>(bind); else s << getInteger<int>(bind); break; case MYSQL_TYPE_LONGLONG: if (bind.is_unsigned) s << *static_cast<long long unsigned*>(bind.buffer); else s << *static_cast<long long int*>(bind.buffer); break; case MYSQL_TYPE_FLOAT: s << *static_cast<float*>(bind.buffer); break; case MYSQL_TYPE_DOUBLE: s << *static_cast<double*>(bind.buffer); break; default: log_error("type-error in getString, type=" << bind.buffer_type); throw TypeError("type-error in getString"); } ret.assign(s.str()); } } }
int ValueImpl::getInt() const { if (null) throw NullValue(); return getValue<int>(data, "int"); }
unsigned ValueImpl::getUnsigned() const { if (null) throw NullValue(); return getValue<unsigned>(data, "unsigned"); }
unsigned short ValueImpl::getUnsignedShort() const { if (null) throw NullValue(); return getValue<unsigned short>(data, "unsigned short"); }
unsigned long ValueImpl::getUnsignedLong() const { if (null) throw NullValue(); return getValue<unsigned long>(data, "unsigned long"); }