All Downloads are FREE. Search and download functionalities are using the official Maven repository.

node_modules.smrf-native.src.smrf.cpp Maven / Gradle / Ivy

There is a newer version: 1.4.0
Show newest version
/*
 * #%L
 * %%
 * Copyright (C) 2017 BMW Car IT GmbH
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

#include 
#include 
#include 
#include 
#include 

#include 
#include 

#include 
#include 
#include 
#include 

#include "MessageDeserializerWrapper.h"
#include "Strings.h"
#include "marshalling.h"
#include "util.h"

NAN_METHOD(serialize)
{
    using marshalling::convertFromV8;
    using marshalling::getMemberValue;
    using marshalling::getOptionalMemberValue;
    using v8::Local;

    const std::size_t requiredArgCount = 1;

    if (info.Length() != requiredArgCount) {
        return Nan::ThrowError("invalid number of arguments");
    }

    smrf::MessageSerializer serializer;
    // iterate over arguments, pass them on to the serializer
    v8::Local context = info[0].As();
    std::string sender;
    std::string recipient;
    std::int64_t ttlMs;
    bool isCompressed;
    bool isTtlAbsolute;

    smrf::ByteVector serializedMessage;

    try {
        convertFromV8(getMemberValue(context, Strings::get().sender), sender);
        serializer.setSender(sender);

        convertFromV8(getMemberValue(context, Strings::get().recipient), recipient);
        serializer.setRecipient(recipient);

        convertFromV8(getMemberValue(context, Strings::get().ttlMs), ttlMs);
        serializer.setTtlMs(ttlMs);

        convertFromV8(getMemberValue(context, Strings::get().isTtlAbsolute), isTtlAbsolute);
        serializer.setTtlAbsolute(isTtlAbsolute);

        convertFromV8(getMemberValue(context, Strings::get().isCompressed), isCompressed);
        serializer.setCompressed(isCompressed);

        using OptionalV8Value = boost::optional>;
        OptionalV8Value cb = getOptionalMemberValue(context, "signingCallback");

        if (cb) {
            // It MUST NOT copy the argument it is invoked with
            // it MUST be a synchronous function
            std::function signingCallback =
                    [&cb, &context](const smrf::ByteArrayView& msg) {
                        v8::Local msgBuffer = util::bufferWitNoOpFreeCallback(msg);
                        const unsigned argc = 1;
                        v8::Local argv[] = {msgBuffer};
                        v8::Local signatureBuffer = cb->As()->Call(context, argc, argv);
                        smrf::ByteVector signature = util::bufferToByteVector(signatureBuffer);
                        return signature;
                    };

            serializer.setCustomSigningCallback(std::move(signingCallback));
        }

        v8::Local bufferValue = getMemberValue(context, Strings::get().body);
        if (!node::Buffer::HasInstance(bufferValue)) {
            return Nan::ThrowTypeError("'body' must be a buffer");
        }
        smrf::ByteArrayView bufferView = util::bufferToByteArrayView(bufferValue->ToObject());
        serializer.setBody(bufferView);

        v8::Local headersValue = getMemberValue(context, Strings::get().headers);
        if (!headersValue->IsObject()) {
            return Nan::ThrowTypeError("'headers' must be an object");
        }
        v8::Local headers = headersValue->ToObject();
        Nan::MaybeLocal maybeProperties = Nan::GetOwnPropertyNames(headers);
        if (!maybeProperties.IsEmpty()) {
            v8::Local properties = maybeProperties.ToLocalChecked();
            const std::size_t headerCount = properties->Length();
            std::unordered_map headerMap(headerCount);
            for (std::size_t i = 0; i < headerCount; ++i) {
                v8::Local key = properties->Get(i);
                std::string keyStr;
                convertFromV8(key, keyStr);

                v8::Local value = headers->Get(key);
                std::string valueStr;
                convertFromV8(value, valueStr);

                headerMap.emplace(std::move(keyStr), std::move(valueStr));
            }
            serializer.setHeaders(headerMap);
        }
        // finally, serialize the message
        serializedMessage = serializer.serialize();
        // finally, serialize the message and return the resulting buffer
        info.GetReturnValue().Set(util::byteVectorToBuffer(std::move(serializedMessage)));

    } catch (const std::invalid_argument& e) {
        return Nan::ThrowTypeError(e.what());
    }
}

NAN_MODULE_INIT(Init)
{
    Strings::init();
    MessageDeserializerWrapper::Init(target);
    using namespace Nan;
    Set(target, util::string("serialize"), New(serialize)->GetFunction());
}

NODE_MODULE(smrf_native, Init)




© 2015 - 2025 Weber Informatics LLC | Privacy Policy