c++ - 将缓冲区转换为 istream 以在现有程序中工作

标签 c++ node.js

我正在尝试创建一个本地 nodejs 模块,使用 NANc++,我想转换一个使用 std::ifstream 的现有程序stream (filename, std::ifstream::in | std::ifstream::binary); 将文件加载到可以加载缓冲区并将其发送到 c++ 的 javascript 模块中

原始的 c++ 代码是通过命令行工作的,我不想将文件写入磁盘,我想使用 nodejs 缓冲区发送这个文件。

索引.js

const fs = require('fs')
const addon = require('./build/Release/image_edit');

fs.readFile('image.png', function read(err, buffer) {
    if (err) {
        throw err;
    }

    var result = addon.edit(buffer, buffer.length);
    //console.log(result)

});

主要.cpp

#include <node.h>
#include <node_buffer.h>
#include <iostream>
#include <nan.h>
#include <sstream>
#include <string>
#include <fstream>
#include <streambuf>
#include <istream>

using namespace Nan;
using namespace v8;

uint32_t read(std::istream& in)
{
    uint32_t v;
    in.read(reinterpret_cast<char*>(&v), sizeof(v));
    return v;
}

NAN_METHOD(edit) {

    unsigned char*buffer = (unsigned char*) node::Buffer::Data(info[0]->ToObject());
    unsigned int size = info[1]->Uint32Value();

    //the closest I could to manipulating the data was using a vector
    std::vector<uint32_t> png_data(buffer, buffer + size);

    //The main core of the program uses the in.read function to parse the file, tb uses in.clear () and in.seekg ();
    //here an example of how this is done
    uint32_t count = readU32(stream);


}

NAN_MODULE_INIT(Init) {
   Nan::Set(target, New<String>("edit").ToLocalChecked(),
        GetFunction(New<FunctionTemplate>(edit)).ToLocalChecked());
}

NODE_MODULE(image_edit, Init)

我尝试使用以下代码来验证接收到的数据是否有效,如果记录的文件与原始文件相同,一切看起来都很好。

std::ofstream FILE("test.png", std::ios::out | std::ofstream::binary);
        std::copy(png_data.begin(), png_data.end(), std::ostreambuf_iterator<char>(FILE));

问题是,如何使从 nodejs 接收到的缓冲区以与 ifstream 相同的方式读取,而不必彻底更改 C++ 程序?

c++中程序调用的方法主要有:.seekg().push_back.clear()

最佳答案

这种事情通常是通过实现std::streambuf的自定义子类,然后用它构造一个std::istream来完成的。

std::istream 有一个构造函数,它接受一个指向 std::streambuf 的指针作为参数,所以基本的轮廓是这样的

class my_streambuf : public std::streambuf {

      // ... Your implementation of your subclass
};

my_streambuf msb{ /* Parameters to your class's constructor */ }

std::istream i{&msb};

在这一点上,i 是一个普通的输入流,可以做任何其他输入流所做的一切。你可以去寻找它。您可以从中阅读。

当然,最困难的部分是实现您自定义的 std::streambuf 子类。这不是在 stackoverflow.com 上的一两段中可以完全描述的事情。你应该read std::streambuf's documentation ,特别是它的虚拟方法的描述。您的自定义子类将需要重新实现 std::streambuf 的虚拟方法,并使它们与您的 buffer 一起工作。您很可能不需要重新实现所有虚拟方法。对于它们中的一些,它们的默认实现就足够了。对于您最终使用 std::istream 所做的事情,将不需要其中一些。

您必须根据您的具体需求确定您需要在多大程度上重新实现 std::streambuf 的虚拟方法,以及如何重新实现。

当然,另一个简单的替代方法是使用您的缓冲区构造一个 std::string,然后用它构造一个 std::istringstream,然后今天就这样吧。当然,这会有些浪费,并且需要有效地将用于数据的内存加倍,并使用一次性 std::string 拥有的第二个拷贝,然后复制它。如果这是少量数据可能没问题,但如果您的 buffer 非常大可能不实用,并且自定义 std::streambuf 子类使用buffer 直接是你唯一的选择。

关于c++ - 将缓冲区转换为 istream 以在现有程序中工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57337940/

相关文章:

c++ - SFML 组合可绘制对象

json - 无法解析 AWS.EC2.describeInstances() 方法在 nodejs API 中返回的 JSON

c++ - C++中不同对象的多个链表

c++ - 在 C++ 中读取 Windows 注册表项 REG_BINARY

node.js - 如何在 vagrant Provision shell 中为 Node 运行永久工具

json - Node 红色:Raspberry Pi 上的 "Error: inject node not deployed"

node.js - NodeJS - 我的应用程序无法启动

javascript - 我可以在 Sublime 2 中调试 node.js 应用程序吗?

c++ - 变量后的 Doxygen 多行注释

c++ - 共享成员静态或动态内存分配 C++