Implement pushing of MIME data to Jupyter.

This commit is contained in:
Axel Naumann 2015-12-10 15:20:01 +01:00 committed by sftnight
parent 8e8fb11831
commit 2352b5e745

View File

@ -2,9 +2,63 @@
// Created by Axel Naumann on 09/12/15.
//
//#include "cling/Interpreter/Jupyter/Kernel.h"
#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/Value.h"
#include <map>
#include <string>
namespace cling {
namespace Jupyter {
struct MIMEDataRef {
const char* m_Data;
const long m_Size;
MIMEDataRef(const std::string& str):
m_Data(str.c_str()), m_Size((long)str.length() + 1) {}
MIMEDataRef(const char* str):
MIMEDataRef(std::string(str)) {}
MIMEDataRef(const char* data, long size):
m_Data(data), m_Size(size) {}
};
/// Push MIME stuff to Jupyter. To be called from user code.
///\param contentDict - dictionary of MIME type versus content. E.g.
/// {{"text/html", {"<div></div>", }}
void pushOutput(const std::map<std::string, MIMEDataRef> contentDict) {
FILE* outpipe = popen("???", "w");
// Pipe sees (all numbers are longs, except for the first:
// - num bytes in a long (sent as a single unsigned char!)
// - num elements of the MIME dictionary; Jupyter selects one to display.
// For each MIME dictionary element:
// - MIME type as 0-terminated string
// - size of MIME data buffer (including the terminating 0 for
// 0-terminated strings)
// - MIME data buffer
// Write number of dictionary elements (and the size of that number in a
// char)
unsigned char sizeLong = sizeof(long);
fwrite(&sizeLong, 1, 1, outpipe);
long dictSize = contentDict.size();
fwrite(&dictSize, sizeof(long), 1, outpipe);
for (auto iContent: contentDict) {
const std::string& mimeType = iContent.first;
fwrite(mimeType.c_str(), mimeType.size() + 1, 1, outpipe);
const MIMEDataRef& mimeData = iContent.second;
fwrite(&mimeData.m_Size, sizeof(long), 1, outpipe);
fwrite(mimeData.m_Data, mimeData.m_Size, 1, outpipe);
}
pclose(outpipe);
}
} // namespace Jupyter
} // namespace cling
extern "C" {
///\{
///\name Cling4CTypes
@ -14,7 +68,8 @@ extern "C" {
using TheInterpreter = void ;
/// Create an interpreter object.
TheInterpreter *cling_create(int argc, const char *argv[], const char* llvmdir) {
TheInterpreter*
cling_create(int argc, const char *argv[], const char* llvmdir) {
auto interp = new cling::Interpreter(argc, argv, llvmdir);
return interp;
}
@ -34,8 +89,10 @@ int cling_eval(TheInterpreter *interpVP, const char *code) {
cling::Interpreter::CompilationResult Res = interp->process(code /*, V*/);
if (Res != cling::Interpreter::kSuccess)
return 1;
cling::Jupyter::pushOutput({{"text/html", "You just executed C++ code!"}});
return 0;
}
///\}
} // extern "C"