Search code examples
c++mongodbbson

libbson help to read data into object C++


i have my unreal project that must read out some BSON document data into a map.

right now i'm able to load that file and print it out with the following code :

void AMyActor::BeginPlay()
{
    Super::BeginPlay();

    std::ifstream input( filePath , std::ios::binary );
    std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(input), {});

    bson_t* doc{ bson_new_from_data(buffer.data(),buffer.size()) };
    char *str;
    if( doc != nullptr )
    {
        UE_LOG(LogTemp,Warning,TEXT( "Success" ));

        str = bson_as_json(doc, NULL);
        
        FString fstr = FString(UTF8_TO_TCHAR(str));
        
        UE_LOG(LogTemp, Warning, TEXT("BSON Output: %s"), *fstr);       
    }
}

and this is here is where i want to store it :

class Databases
{
    std::map<std::string,DatabaseBase> _dictionary;

    explicit Databases(const std::map<std::string, DatabaseBase>& dictionary)
        : _dictionary(dictionary)
    {
    }
};

so what i'm looking for is to create a new instance of Databases and initialize "_dictionary" with the content of the bson document.

i'm actually looking for this into the libbson document : http://mongoc.org/libbson/current/bson_t.html

but without success...anyone can help me?

thank's in advance

PS: i'm under unreal but i have linked the libbson library

Update: since i have to provide how my json file looks like, and DatabaseBase looks like

JSON :

{
  "_dictionary" : [ {
      "_classID" : "CC00",
      "_dictionary" : [ {
          "k" : "sample_key",
          "v" : ["ACH_00"]
        }, {
          "k" : "sample_index",
          "v" : ["0"]
        }]
    }, {
      "_classID" : "CC01",
      "_dictionary" : [ {
          "k" : "sample_key",
          "v" : ["ACH_01"]
        }, {
          "k" : "sample_index",
          "v" : ["1"]
        }]
    }]
}

DatabaseBase :

class DatabaseBase
{
public:
    DatabaseBase() = default;

    std::string sample_key;
    int sample_index; 
};

Solution

  • Breaking out nlohmann::json:

        using nlohmann::json;
        std::map<std::string, DatabaseBase> dictionaries;
        json input = json::from_bson(buffer);
        for (auto& obj : input["_dictionary"]) {
            auto name = obj["_classID"];
            auto key = obj["_dictionary"][0]["v"][0];
            auto idx = stoi(obj["_dictionary"][1]["v"][0].get<std::string>());
            auto db = DatabaseBase{key, idx};
            dictionaries[name] = db;
        }
        Databases dbs{dictionaries};
    

    output: (from my debugger)

    (lldb) p dbs
    (Databases) $0 = {
      _dictionary = size=2 {
        [0] = {
          first = "CC00"
          second = (sample_key = "ACH_00", sample_index = 0)
        }
        [1] = {
          first = "CC01"
          second = (sample_key = "ACH_01", sample_index = 1)
        }
      }
    }