Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/js/xpconnect/src/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 22 kB image not shown  

Quelle  XPCVariant.cpp   Sprache: C

 
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


/* nsIVariant implementation for xpconnect. */

#include "mozilla/Range.h"

#include "xpcprivate.h"

#include "jsfriendapi.h"
#include "js/Array.h"  // JS::GetArrayLength, JS::IsArrayObject, JS::NewArrayObject
#include "js/friend/StackLimits.h"  // js::AutoCheckRecursionLimit
#include "js/friend/WindowProxy.h"  // js::ToWindowIfWindowProxy
#include "js/PropertyAndElement.h"  // JS_GetElement
#include "js/Wrapper.h"
#include "mozilla/HoldDropJSObjects.h"

using namespace JS;
using namespace mozilla;
using namespace xpc;

NS_IMPL_CLASSINFO(XPCVariant, nullptr, 0, XPCVARIANT_CID)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(XPCVariant)
  NS_INTERFACE_MAP_ENTRY(XPCVariant)
  NS_INTERFACE_MAP_ENTRY(nsIVariant)
  NS_INTERFACE_MAP_ENTRY(nsISupports)
  NS_IMPL_QUERY_CLASSINFO(XPCVariant)
NS_INTERFACE_MAP_END
NS_IMPL_CI_INTERFACE_GETTER(XPCVariant, XPCVariant, nsIVariant)

NS_IMPL_CYCLE_COLLECTING_ADDREF(XPCVariant)
NS_IMPL_CYCLE_COLLECTING_RELEASE(XPCVariant)

XPCVariant::XPCVariant(JSContext* cx, const Value& aJSVal) : mJSVal(aJSVal) {
  if (!mJSVal.isPrimitive()) {
    // XXXbholley - The innerization here was from bug 638026. Blake says
    // the basic problem was that we were storing the C++ inner but the JS
    // outer, which meant that, after navigation, the JS inner could be
    // collected, which would cause us to try to recreate the JS inner at
    // some later point after teardown, which would crash. This is shouldn't
    // be a problem anymore because SetParentToWindow will do the right
    // thing, but I'm saving the cleanup here for another day. Blake thinks
    // that we should just not store the WN if we're creating a variant for
    // an outer window.
    JSObject* obj = js::ToWindowIfWindowProxy(&mJSVal.toObject());
    mJSVal = JS::ObjectValue(*obj);

    JSObject* unwrapped =
        js::CheckedUnwrapDynamic(obj, cx, /* stopAtWindowProxy = */ false);
    mReturnRawObject = !(unwrapped && IsWrappedNativeReflector(unwrapped));
  } else {
    mReturnRawObject = false;
  }

  if (aJSVal.isGCThing()) {
    mozilla::HoldJSObjects(this);
  }
}

XPCVariant::~XPCVariant() { Cleanup(); }

NS_IMPL_CYCLE_COLLECTION_CLASS(XPCVariant)

NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(XPCVariant)
  tmp->mData.Traverse(cb);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END

NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(XPCVariant)
  tmp->Cleanup();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END

NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(XPCVariant)
  NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mJSVal)
NS_IMPL_CYCLE_COLLECTION_TRACE_END

// static
already_AddRefed<XPCVariant> XPCVariant::newVariant(JSContext* cx,
                                                    const Value& aJSVal) {
  RefPtr<XPCVariant> variant = new XPCVariant(cx, aJSVal);
  if (!variant->InitializeData(cx)) {
    return nullptr;
  }

  return variant.forget();
}

void XPCVariant::Cleanup() {
  mData.Cleanup();

  if (!GetJSValPreserveColor().isGCThing()) {
    return;
  }
  mJSVal = JS::NullValue();
  mozilla::DropJSObjects(this);
}

// Helper class to give us a namespace for the table based code below.
class XPCArrayHomogenizer {
 private:
  enum Type {
    tNull = 0,  // null value
    tInt,       // Integer
    tDbl,       // Double
    tBool,      // Boolean
    tStr,       // String
    tID,        // ID
    tArr,       // Array
    tISup,      // nsISupports (really just a plain JSObject)
    tUnk,       // Unknown. Used only for initial state.

    tTypeCount,  // Just a count for table dimensioning.

    tVar,  // nsVariant - last ditch if no other common type found.
    tErr   // No valid state or type has this value.
  };

  // Table has tUnk as a state (column) but not as a type (row).
  static const Type StateTable[tTypeCount][tTypeCount - 1];

 public:
  static bool GetTypeForArray(JSContext* cx, HandleObject array,
                              uint32_t length, nsXPTType* resultType,
                              nsID* resultID);
};

// Current state is the column down the side.
// Current type is the row along the top.
// New state is in the box at the intersection.

const XPCArrayHomogenizer::Type
    XPCArrayHomogenizer::StateTable[tTypeCount][tTypeCount - 1] = {
        /*          tNull,tInt ,tDbl ,tBool,tStr ,tID  ,tArr ,tISup */
        /* tNull */ {tNull, tVar, tVar, tVar, tStr, tID, tVar, tISup},
        /* tInt  */ {tVar, tInt, tDbl, tVar, tVar, tVar, tVar, tVar},
        /* tDbl  */ {tVar, tDbl, tDbl, tVar, tVar, tVar, tVar, tVar},
        /* tBool */ {tVar, tVar, tVar, tBool, tVar, tVar, tVar, tVar},
        /* tStr  */ {tStr, tVar, tVar, tVar, tStr, tVar, tVar, tVar},
        /* tID   */ {tID, tVar, tVar, tVar, tVar, tID, tVar, tVar},
        /* tArr  */ {tErr, tErr, tErr, tErr, tErr, tErr, tErr, tErr},
        /* tISup */ {tISup, tVar, tVar, tVar, tVar, tVar, tVar, tISup},
        /* tUnk  */ {tNull, tInt, tDbl, tBool, tStr, tID, tVar, tISup}};

// static
bool XPCArrayHomogenizer::GetTypeForArray(JSContext* cx, HandleObject array,
                                          uint32_t length,
                                          nsXPTType* resultType,
                                          nsID* resultID) {
  Type state = tUnk;
  Type type;

  RootedValue val(cx);
  RootedObject jsobj(cx);
  for (uint32_t i = 0; i < length; i++) {
    if (!JS_GetElement(cx, array, i, &val)) {
      return false;
    }

    if (val.isInt32()) {
      type = tInt;
    } else if (val.isDouble()) {
      type = tDbl;
    } else if (val.isBoolean()) {
      type = tBool;
    } else if (val.isUndefined() || val.isSymbol() || val.isBigInt()) {
      state = tVar;
      break;
    } else if (val.isNull()) {
      type = tNull;
    } else if (val.isString()) {
      type = tStr;
    } else {
      MOZ_RELEASE_ASSERT(val.isObject(), "invalid type of jsval!");
      jsobj = &val.toObject();

      bool isArray;
      if (!JS::IsArrayObject(cx, jsobj, &isArray)) {
        return false;
      }

      if (isArray) {
        type = tArr;
      } else if (xpc::JSValue2ID(cx, val)) {
        type = tID;
      } else {
        type = tISup;
      }
    }

    MOZ_ASSERT(state != tErr, "bad state table!");
    MOZ_ASSERT(type != tErr, "bad type!");
    MOZ_ASSERT(type != tVar, "bad type!");
    MOZ_ASSERT(type != tUnk, "bad type!");

    state = StateTable[state][type];

    MOZ_ASSERT(state != tErr, "bad state table!");
    MOZ_ASSERT(state != tUnk, "bad state table!");

    if (state == tVar) {
      break;
    }
  }

  switch (state) {
    case tInt:
      *resultType = nsXPTType::MkArrayType(nsXPTType::Idx::INT32);
      break;
    case tDbl:
      *resultType = nsXPTType::MkArrayType(nsXPTType::Idx::DOUBLE);
      break;
    case tBool:
      *resultType = nsXPTType::MkArrayType(nsXPTType::Idx::BOOL);
      break;
    case tStr:
      *resultType = nsXPTType::MkArrayType(nsXPTType::Idx::PWSTRING);
      break;
    case tID:
      *resultType = nsXPTType::MkArrayType(nsXPTType::Idx::NSIDPTR);
      break;
    case tISup:
      *resultType = nsXPTType::MkArrayType(nsXPTType::Idx::INTERFACE_IS_TYPE);
      *resultID = NS_GET_IID(nsISupports);
      break;
    case tNull:
      // FALL THROUGH
    case tVar:
      *resultType = nsXPTType::MkArrayType(nsXPTType::Idx::INTERFACE_IS_TYPE);
      *resultID = NS_GET_IID(nsIVariant);
      break;
    case tArr:
      // FALL THROUGH
    case tUnk:
      // FALL THROUGH
    case tErr:
      // FALL THROUGH
    default:
      NS_ERROR("bad state");
      return false;
  }
  return true;
}

bool XPCVariant::InitializeData(JSContext* cx) {
  js::AutoCheckRecursionLimit recursion(cx);
  if (!recursion.check(cx)) {
    return false;
  }

  RootedValue val(cx, GetJSVal());

  if (val.isInt32()) {
    mData.SetFromInt32(val.toInt32());
    return true;
  }
  if (val.isDouble()) {
    mData.SetFromDouble(val.toDouble());
    return true;
  }
  if (val.isBoolean()) {
    mData.SetFromBool(val.toBoolean());
    return true;
  }
  // We can't represent symbol or BigInt on C++ side, so pretend it is void.
  if (val.isUndefined() || val.isSymbol() || val.isBigInt()) {
    mData.SetToVoid();
    return true;
  }
  if (val.isNull()) {
    mData.SetToEmpty();
    return true;
  }
  if (val.isString()) {
    RootedString str(cx, val.toString());
    if (!str) {
      return false;
    }

    MOZ_ASSERT(mData.GetType() == nsIDataType::VTYPE_EMPTY,
               "Why do we already have data?");

    size_t length = JS_GetStringLength(str);
    mData.AllocateWStringWithSize(length);

    mozilla::Range<char16_t> destChars(mData.u.wstr.mWStringValue, length);
    if (!JS_CopyStringChars(cx, destChars, str)) {
      return false;
    }

    MOZ_ASSERT(mData.u.wstr.mWStringValue[length] == '\0');
    return true;
  }
  if (Maybe<nsID> id = xpc::JSValue2ID(cx, val)) {
    mData.SetFromID(id.ref());
    return true;
  }

  // leaving only JSObject...
  MOZ_RELEASE_ASSERT(val.isObject(), "invalid type of jsval!");

  RootedObject jsobj(cx, &val.toObject());

  // Let's see if it is a js array object.

  uint32_t len;

  bool isArray;
  if (!JS::IsArrayObject(cx, jsobj, &isArray) ||
      (isArray && !JS::GetArrayLength(cx, jsobj, &len))) {
    return false;
  }

  if (isArray) {
    if (!len) {
      // Zero length array
      mData.SetToEmptyArray();
      return true;
    }

    nsXPTType type;
    nsID id;

    if (!XPCArrayHomogenizer::GetTypeForArray(cx, jsobj, len, &type, &id)) {
      return false;
    }

    if (!XPCConvert::JSData2Native(cx, &mData.u.array.mArrayValue, val, type,
                                   &id, len, nullptr))
      return false;

    const nsXPTType& elty = type.ArrayElementType();
    mData.mType = nsIDataType::VTYPE_ARRAY;
    if (elty.IsInterfacePointer()) {
      mData.u.array.mArrayInterfaceID = id;
    }
    mData.u.array.mArrayCount = len;
    mData.u.array.mArrayType = elty.Tag();

    return true;
  }

  // XXX This could be smarter and pick some more interesting iface.

  nsIXPConnect* xpc = nsIXPConnect::XPConnect();
  nsCOMPtr<nsISupports> wrapper;
  const nsIID& iid = NS_GET_IID(nsISupports);

  if (NS_FAILED(xpc->WrapJS(cx, jsobj, iid, getter_AddRefs(wrapper)))) {
    return false;
  }

  mData.SetFromInterface(iid, wrapper);
  return true;
}

NS_IMETHODIMP
XPCVariant::GetAsJSVal(MutableHandleValue result) {
  result.set(GetJSVal());
  return NS_OK;
}

// static
bool XPCVariant::VariantDataToJS(JSContext* cx, nsIVariant* variant,
                                 nsresult* pErr, MutableHandleValue pJSVal) {
  // Get the type early because we might need to spoof it below.
  uint16_t type = variant->GetDataType();

  RootedValue realVal(cx);
  nsresult rv = variant->GetAsJSVal(&realVal);

  if (NS_SUCCEEDED(rv) &&
      (realVal.isPrimitive() || type == nsIDataType::VTYPE_ARRAY ||
       type == nsIDataType::VTYPE_EMPTY_ARRAY ||
       type == nsIDataType::VTYPE_ID)) {
    if (!JS_WrapValue(cx, &realVal)) {
      return false;
    }
    pJSVal.set(realVal);
    return true;
  }

  nsCOMPtr<XPCVariant> xpcvariant = do_QueryInterface(variant);
  if (xpcvariant && xpcvariant->mReturnRawObject) {
    MOZ_ASSERT(type == nsIDataType::VTYPE_INTERFACE ||
                   type == nsIDataType::VTYPE_INTERFACE_IS,
               "Weird variant");

    if (!JS_WrapValue(cx, &realVal)) {
      return false;
    }
    pJSVal.set(realVal);
    return true;
  }

  // else, it's an object and we really need to double wrap it if we've
  // already decided that its 'natural' type is as some sort of interface.

  // We just fall through to the code below and let it do what it does.

  // The nsIVariant is not a XPCVariant (or we act like it isn't).
  // So we extract the data and do the Right Thing.

  // We ASSUME that the variant implementation can do these conversions...

  nsID iid;

  switch (type) {
    case nsIDataType::VTYPE_INT8:
    case nsIDataType::VTYPE_INT16:
    case nsIDataType::VTYPE_INT32:
    case nsIDataType::VTYPE_INT64:
    case nsIDataType::VTYPE_UINT8:
    case nsIDataType::VTYPE_UINT16:
    case nsIDataType::VTYPE_UINT32:
    case nsIDataType::VTYPE_UINT64:
    case nsIDataType::VTYPE_FLOAT:
    case nsIDataType::VTYPE_DOUBLE: {
      double d;
      if (NS_FAILED(variant->GetAsDouble(&d))) {
        return false;
      }
      pJSVal.set(JS_NumberValue(d));
      return true;
    }
    case nsIDataType::VTYPE_BOOL: {
      bool b;
      if (NS_FAILED(variant->GetAsBool(&b))) {
        return false;
      }
      pJSVal.setBoolean(b);
      return true;
    }
    case nsIDataType::VTYPE_CHAR: {
      char c;
      if (NS_FAILED(variant->GetAsChar(&c))) {
        return false;
      }
      return XPCConvert::NativeData2JS(cx, pJSVal, (const void*)&c, {TD_CHAR},
                                       &iid, 0, pErr);
    }
    case nsIDataType::VTYPE_WCHAR: {
      char16_t wc;
      if (NS_FAILED(variant->GetAsWChar(&wc))) {
        return false;
      }
      return XPCConvert::NativeData2JS(cx, pJSVal, (const void*)&wc, {TD_WCHAR},
                                       &iid, 0, pErr);
    }
    case nsIDataType::VTYPE_ID: {
      if (NS_FAILED(variant->GetAsID(&iid))) {
        return false;
      }
      nsID* v = &iid;
      return XPCConvert::NativeData2JS(cx, pJSVal, (const void*)&v,
                                       {TD_NSIDPTR}, &iid, 0, pErr);
    }
    case nsIDataType::VTYPE_ASTRING: {
      nsAutoString astring;
      if (NS_FAILED(variant->GetAsAString(astring))) {
        return false;
      }
      return XPCConvert::NativeData2JS(cx, pJSVal, &astring, {TD_ASTRING}, &iid,
                                       0, pErr);
    }
    case nsIDataType::VTYPE_CSTRING: {
      nsAutoCString cString;
      if (NS_FAILED(variant->GetAsACString(cString))) {
        return false;
      }
      return XPCConvert::NativeData2JS(cx, pJSVal, &cString, {TD_CSTRING}, &iid,
                                       0, pErr);
    }
    case nsIDataType::VTYPE_UTF8STRING: {
      nsUTF8String utf8String;
      if (NS_FAILED(variant->GetAsAUTF8String(utf8String))) {
        return false;
      }
      return XPCConvert::NativeData2JS(cx, pJSVal, &utf8String, {TD_UTF8STRING},
                                       &iid, 0, pErr);
    }
    case nsIDataType::VTYPE_CHAR_STR: {
      char* pc;
      if (NS_FAILED(variant->GetAsString(&pc))) {
        return false;
      }
      bool success = XPCConvert::NativeData2JS(cx, pJSVal, (const void*)&pc,
                                               {TD_PSTRING}, &iid, 0, pErr);
      free(pc);
      return success;
    }
    case nsIDataType::VTYPE_STRING_SIZE_IS: {
      char* pc;
      uint32_t size;
      if (NS_FAILED(variant->GetAsStringWithSize(&size, &pc))) {
        return false;
      }
      bool success = XPCConvert::NativeData2JS(
          cx, pJSVal, (const void*)&pc, {TD_PSTRING_SIZE_IS}, &iid, size, pErr);
      free(pc);
      return success;
    }
    case nsIDataType::VTYPE_WCHAR_STR: {
      char16_t* pwc;
      if (NS_FAILED(variant->GetAsWString(&pwc))) {
        return false;
      }
      bool success = XPCConvert::NativeData2JS(cx, pJSVal, (const void*)&pwc,
                                               {TD_PSTRING}, &iid, 0, pErr);
      free(pwc);
      return success;
    }
    case nsIDataType::VTYPE_WSTRING_SIZE_IS: {
      char16_t* pwc;
      uint32_t size;
      if (NS_FAILED(variant->GetAsWStringWithSize(&size, &pwc))) {
        return false;
      }
      bool success =
          XPCConvert::NativeData2JS(cx, pJSVal, (const void*)&pwc,
                                    {TD_PWSTRING_SIZE_IS}, &iid, size, pErr);
      free(pwc);
      return success;
    }
    case nsIDataType::VTYPE_INTERFACE:
    case nsIDataType::VTYPE_INTERFACE_IS: {
      nsISupports* pi;
      nsID* piid;
      if (NS_FAILED(variant->GetAsInterface(&piid, (void**)&pi))) {
        return false;
      }

      iid = *piid;
      free((char*)piid);

      bool success = XPCConvert::NativeData2JS(
          cx, pJSVal, (const void*)&pi, {TD_INTERFACE_IS_TYPE}, &iid, 0, pErr);
      if (pi) {
        pi->Release();
      }
      return success;
    }
    case nsIDataType::VTYPE_ARRAY: {
      nsDiscriminatedUnion du;
      nsresult rv;

      rv = variant->GetAsArray(
          &du.u.array.mArrayType, &du.u.array.mArrayInterfaceID,
          &du.u.array.mArrayCount, &du.u.array.mArrayValue);
      if (NS_FAILED(rv)) {
        return false;
      }

      // must exit via VARIANT_DONE from here on...
      du.mType = nsIDataType::VTYPE_ARRAY;

      uint16_t elementType = du.u.array.mArrayType;
      const nsID* pid = nullptr;

      nsXPTType::Idx xptIndex;
      switch (elementType) {
        case nsIDataType::VTYPE_INT8:
          xptIndex = nsXPTType::Idx::INT8;
          break;
        case nsIDataType::VTYPE_INT16:
          xptIndex = nsXPTType::Idx::INT16;
          break;
        case nsIDataType::VTYPE_INT32:
          xptIndex = nsXPTType::Idx::INT32;
          break;
        case nsIDataType::VTYPE_INT64:
          xptIndex = nsXPTType::Idx::INT64;
          break;
        case nsIDataType::VTYPE_UINT8:
          xptIndex = nsXPTType::Idx::UINT8;
          break;
        case nsIDataType::VTYPE_UINT16:
          xptIndex = nsXPTType::Idx::UINT16;
          break;
        case nsIDataType::VTYPE_UINT32:
          xptIndex = nsXPTType::Idx::UINT32;
          break;
        case nsIDataType::VTYPE_UINT64:
          xptIndex = nsXPTType::Idx::UINT64;
          break;
        case nsIDataType::VTYPE_FLOAT:
          xptIndex = nsXPTType::Idx::FLOAT;
          break;
        case nsIDataType::VTYPE_DOUBLE:
          xptIndex = nsXPTType::Idx::DOUBLE;
          break;
        case nsIDataType::VTYPE_BOOL:
          xptIndex = nsXPTType::Idx::BOOL;
          break;
        case nsIDataType::VTYPE_CHAR:
          xptIndex = nsXPTType::Idx::CHAR;
          break;
        case nsIDataType::VTYPE_WCHAR:
          xptIndex = nsXPTType::Idx::WCHAR;
          break;
        case nsIDataType::VTYPE_ID:
          xptIndex = nsXPTType::Idx::NSIDPTR;
          break;
        case nsIDataType::VTYPE_CHAR_STR:
          xptIndex = nsXPTType::Idx::PSTRING;
          break;
        case nsIDataType::VTYPE_WCHAR_STR:
          xptIndex = nsXPTType::Idx::PWSTRING;
          break;
        case nsIDataType::VTYPE_INTERFACE:
          pid = &NS_GET_IID(nsISupports);
          xptIndex = nsXPTType::Idx::INTERFACE_IS_TYPE;
          break;
        case nsIDataType::VTYPE_INTERFACE_IS:
          pid = &du.u.array.mArrayInterfaceID;
          xptIndex = nsXPTType::Idx::INTERFACE_IS_TYPE;
          break;

        // The rest are illegal.
        case nsIDataType::VTYPE_VOID:
        case nsIDataType::VTYPE_ASTRING:
        case nsIDataType::VTYPE_CSTRING:
        case nsIDataType::VTYPE_UTF8STRING:
        case nsIDataType::VTYPE_WSTRING_SIZE_IS:
        case nsIDataType::VTYPE_STRING_SIZE_IS:
        case nsIDataType::VTYPE_ARRAY:
        case nsIDataType::VTYPE_EMPTY_ARRAY:
        case nsIDataType::VTYPE_EMPTY:
        default:
          NS_ERROR("bad type in array!");
          return false;
      }

      bool success = XPCConvert::NativeData2JS(
          cx, pJSVal, (const void*)&du.u.array.mArrayValue,
          nsXPTType::MkArrayType(xptIndex), pid, du.u.array.mArrayCount, pErr);

      return success;
    }
    case nsIDataType::VTYPE_EMPTY_ARRAY: {
      JSObject* array = JS::NewArrayObject(cx, 0);
      if (!array) {
        return false;
      }
      pJSVal.setObject(*array);
      return true;
    }
    case nsIDataType::VTYPE_VOID:
      pJSVal.setUndefined();
      return true;
    case nsIDataType::VTYPE_EMPTY:
      pJSVal.setNull();
      return true;
    default:
      NS_ERROR("bad type in variant!");
      return false;
  }
}

/***************************************************************************/
/***************************************************************************/
// XXX These default implementations need to be improved to allow for
// some more interesting conversions.

uint16_t XPCVariant::GetDataType() { return mData.GetType(); }

NS_IMETHODIMP XPCVariant::GetAsInt8(uint8_t* _retval) {
  return mData.ConvertToInt8(_retval);
}

NS_IMETHODIMP XPCVariant::GetAsInt16(int16_t* _retval) {
  return mData.ConvertToInt16(_retval);
}

NS_IMETHODIMP XPCVariant::GetAsInt32(int32_t* _retval) {
  return mData.ConvertToInt32(_retval);
}

NS_IMETHODIMP XPCVariant::GetAsInt64(int64_t* _retval) {
  return mData.ConvertToInt64(_retval);
}

NS_IMETHODIMP XPCVariant::GetAsUint8(uint8_t* _retval) {
  return mData.ConvertToUint8(_retval);
}

NS_IMETHODIMP XPCVariant::GetAsUint16(uint16_t* _retval) {
  return mData.ConvertToUint16(_retval);
}

NS_IMETHODIMP XPCVariant::GetAsUint32(uint32_t* _retval) {
  return mData.ConvertToUint32(_retval);
}

NS_IMETHODIMP XPCVariant::GetAsUint64(uint64_t* _retval) {
  return mData.ConvertToUint64(_retval);
}

NS_IMETHODIMP XPCVariant::GetAsFloat(float* _retval) {
  return mData.ConvertToFloat(_retval);
}

NS_IMETHODIMP XPCVariant::GetAsDouble(double* _retval) {
  return mData.ConvertToDouble(_retval);
}

NS_IMETHODIMP XPCVariant::GetAsBool(bool* _retval) {
  return mData.ConvertToBool(_retval);
}

NS_IMETHODIMP XPCVariant::GetAsChar(char* _retval) {
  return mData.ConvertToChar(_retval);
}

NS_IMETHODIMP XPCVariant::GetAsWChar(char16_t* _retval) {
  return mData.ConvertToWChar(_retval);
}

NS_IMETHODIMP_(nsresult) XPCVariant::GetAsID(nsID* retval) {
  return mData.ConvertToID(retval);
}

NS_IMETHODIMP XPCVariant::GetAsAString(nsAString& _retval) {
  return mData.ConvertToAString(_retval);
}

NS_IMETHODIMP XPCVariant::GetAsACString(nsACString& _retval) {
  return mData.ConvertToACString(_retval);
}

NS_IMETHODIMP XPCVariant::GetAsAUTF8String(nsAUTF8String& _retval) {
  return mData.ConvertToAUTF8String(_retval);
}

NS_IMETHODIMP XPCVariant::GetAsString(char** _retval) {
  return mData.ConvertToString(_retval);
}

NS_IMETHODIMP XPCVariant::GetAsWString(char16_t** _retval) {
  return mData.ConvertToWString(_retval);
}

NS_IMETHODIMP XPCVariant::GetAsISupports(nsISupports** _retval) {
  return mData.ConvertToISupports(_retval);
}

NS_IMETHODIMP XPCVariant::GetAsInterface(nsIID** iid, void** iface) {
  return mData.ConvertToInterface(iid, iface);
}

NS_IMETHODIMP_(nsresult)
XPCVariant::GetAsArray(uint16_t* type, nsIID* iid, uint32_t* count,
                       void** ptr) {
  return mData.ConvertToArray(type, iid, count, ptr);
}

NS_IMETHODIMP XPCVariant::GetAsStringWithSize(uint32_t* size, char** str) {
  return mData.ConvertToStringWithSize(size, str);
}

NS_IMETHODIMP XPCVariant::GetAsWStringWithSize(uint32_t* size, char16_t** str) {
  return mData.ConvertToWStringWithSize(size, str);
}

Messung V0.5
C=89 H=93 G=90

¤ Dauer der Verarbeitung: 0.9 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.