Skip to content

Commit

Permalink
finishes initial code; correctly compiles; linkage and buildem tbd
Browse files Browse the repository at this point in the history
  • Loading branch information
Stephen Plaza committed Apr 15, 2014
1 parent ec70863 commit ed4308d
Show file tree
Hide file tree
Showing 11 changed files with 396 additions and 50 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.swp
build
39 changes: 24 additions & 15 deletions BinaryData.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,47 @@
#define BINARYDATA

#include <boost/shared_ptr.hpp>
#include <fstream>
#include <string>

typedef unsigned char byte
namespace libdvid {

typedef unsigned char byte;

class BinaryData;
typedef boost::shared_ptr<BinaryData> BinaryDataPtr;

class BinaryData {
public:
static BinaryDataPtr create_binary_data(byte* data_)
static BinaryDataPtr create_binary_data(const char* data_)
{
return BinaryDataPtr(new BinaryData(data_));
}
char * get_raw()
static BinaryDataPtr create_binary_data(std::ifstream& fin)
{
return data;
return BinaryDataPtr(new BinaryData(fin));
}
~BinaryData()

byte * get_raw()
{
delete data;
return (byte *)(data.c_str());
}

std::string& get_data()
{
return data;
}
~BinaryData() {}
private:
BinaryData(byte data_) : data(data_) {}
byte data;
BinaryData(const char* data_) : data(data_) {}
BinaryData(std::ifstream& fin)
{
data.assign( (std::istreambuf_iterator<char>(fin) ),
(std::istreambuf_iterator<char>() ) );
}
std::string data;
};







}

#endif

92 changes: 92 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
project (libdvidcpp)

include (ExternalProject)

set (RUN_ENVIRONMENT "Workstation" CACHE TYPE STRING)
if (NOT CMAKE_BUILD_TYPE)
set (CMAKE_BUILD_TYPE Release)
endif ()

set (CMAKE_CXX_LINK_FLAGS "-O3")
set (CMAKE_CXX_FLAGS_RELEASE "-O3")
set (CMAKE_CXX_FLAGS_DEBUG "-ggdb")
set (CMAKE_DEBUG_POSTFIX "-g")


################################################################################
# Check if BUILDEM_DIR has already been assigned. If not, create a default.
set (BUILDEM_DIR "None" CACHE TYPE STRING)

if (${BUILDEM_DIR} STREQUAL "None")
message ("WARNING: To use Buildem, Buildem directory (for all downloads & builds) should be specified via -DBUILDEM_DIR=<path> on cmake command line.")
message ("Builds will be placed here: ${CMAKE_SOURCE_DIR}/bin")
else()
message ("FlyEM downloads and builds will be placed here: ${BUILDEM_DIR}")
endif ()
###############################################################################

if (${BUILDEM_DIR} STREQUAL "None")
set (BUILDLOC ${CMAKE_SOURCE_DIR})
else()
set (BUILDLOC ${BUILDEM_DIR})
endif()

if (NOT ${BUILDEM_DIR} STREQUAL "None")
###############################################################################
# Download and install buildem, if it isn't already in BUILDEM_DIR.
set (BUILDEM_REPO_DIR ${BUILDEM_DIR}/src/buildem)
if (NOT EXISTS ${BUILDEM_REPO_DIR}/python.cmake)
message ("Installing buildem repo...")
ExternalProject_Add(buildem
PREFIX ${BUILDEM_DIR}
GIT_REPOSITORY http://github.com/janelia-flyem/buildem.git
UPDATE_COMMAND ""
PATCH_COMMAND ""
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
BUILD_IN_SOURCE 1
INSTALL_COMMAND ""
)
message ("\n**********************************************************\n")
message ("\nAfter running make, you must re-run the cmake command once")
message ("buildem has been downloaded!\n")
message ("\n***********************************************************\n")
return()
endif()
###############################################################################

# Use modules from the downloaded buildem
set (CMAKE_MODULE_PATH ${BUILDEM_REPO_DIR})
message("Using cmake modules from ${BUILDEM_REPO_DIR}")

include (jsoncpp)
include (cppnetlib)
else ()
FIND_PACKAGE(cppnetlib 0.11.0 REQUIRED)
include_directories (BEFORE ${CPPNETLIB_INCLUDE_DIRS})
set (LIBDVID_EXT_LIBS ${CPPNETLIB_LIBRARIES})
endif (NOT ${BUILDEM_DIR} STREQUAL "None")

# set bin and lib directories
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${BUILDLOC}/bin)
if (NOT EXISTS ${BUILDLOC}/bin)
file (MAKE_DIRECTORY ${BUILDLOC}/bin)
endif()

set (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${BUILDLOC}/lib)
set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${BUILDLOC}/lib)
if (NOT EXISTS ${BUILDLOC}/lib)
file (MAKE_DIRECTORY ${BUILDLOC}/lib)
endif()

# Compile libdvidcpp library components
add_library (libdvidcpp SHARED DVIDNode.cpp DVIDServer.cpp)

target_link_libraries (libdvidcpp ${LIBDVID_EXT_LIBS})

if (NOT ${BUILDEM_DIR} STREQUAL "None")
add_dependencies (libdvidcpp ${LIBDVID_DEPS})
endif()


8 changes: 4 additions & 4 deletions DVIDException.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@
#define DVIDEXCEPTION_H

#include "Utilities.h"
#include <ostream>
#include <sstream>

namespace libdvid {

class DVIDException : public ErrMsg {
public:
DVIDException(int status_) :
DVIDException(std::string msg_, int status_) :
ErrMsg(msg_), status(status_) {}

std::string get_msg()
{
std::stringstream sstr;
sstr << status << ": " << ErrMsg::get_msg();
return sstr.string();
sstr << "DVID Error (" << status << "): " << ErrMsg::get_msg();
return sstr.str();
}
private:
int status;
Expand Down
197 changes: 197 additions & 0 deletions DVIDNode.cpp
Original file line number Diff line number Diff line change
@@ -1 +1,198 @@
#include "DVIDNode.h"
#include "DVIDException.h"
#include <boost/network/protocol/http/client.hpp>
#include <json/json.h>
#include <set>

using std::ifstream; using std::set; using std::stringstream;
Json::Reader json_reader;

using namespace boost::network;
using namespace boost::network::http;

namespace libdvid {

DVIDNode::DVIDNode(DVIDServer web_addr_, UUID uuid_) :
web_addr(web_addr_), uuid(uuid_)
{
client::request requestobj(web_addr.get_uri_root() + "node/" + uuid + "/info");
requestobj << header("Connection", "close");
client request_client;
client::response respdata = request_client.get(requestobj);
int status_code = status(respdata);
if (status_code != 200) {
throw DVIDException(body(respdata), status_code);
}
}

void DVIDNode::create_keyvalue(std::string keyvalue)
{
client::request requestobj(web_addr.get_uri_root() + "dataset/" + uuid +
"/new/keyvalue" + keyvalue );
requestobj << header("Connection", "close");
client request_client;

std::string data("{}");
client::response respdata = request_client.post(requestobj,
"application/json", data);
int status_code = status(respdata);
if (status_code != 200) {
throw DVIDException(body(respdata), status_code);
}
}

void DVIDNode::put(std::string keyvalue, std::string key, BinaryDataPtr value)
{
client::request requestobj(web_addr.get_uri_root() + "node/" + uuid +
"/" + keyvalue + "/" + key);
requestobj << header("Connection", "close");
client request_client;

client::response respdata = request_client.post(requestobj,
"application/octet-stream", value->get_data());
int status_code = status(respdata);
if (status_code != 200) {
throw DVIDException(body(respdata), status_code);
}
}

void DVIDNode::put(std::string keyvalue, std::string key, ifstream& fin)
{
BinaryDataPtr data = BinaryData::create_binary_data(fin);
put(keyvalue, key, data);
}


void DVIDNode::put(std::string keyvalue, std::string key, Json::Value& data)
{
stringstream datastr;
datastr << data;
BinaryDataPtr bdata = BinaryData::create_binary_data(datastr.str().c_str());
put(keyvalue, key, bdata);
}


void DVIDNode::get(std::string keyvalue, std::string key, BinaryDataPtr& value)
{
client::request requestobj(web_addr.get_uri_root() + "node/" + uuid +
"/" + keyvalue + "/" + key);
requestobj << header("Connection", "close");
client request_client;
client::response respdata = request_client.get(requestobj);
int status_code = status(respdata);
if (status_code != 200) {
throw DVIDException(body(respdata), status_code);
}
std::string data = body(respdata);
// ?! allow intialization to happen in constructor
value = BinaryData::create_binary_data(data.c_str());
}

void DVIDNode::get(std::string keyvalue, std::string key, Json::Value& data)
{
BinaryDataPtr binary;
get(keyvalue, key, binary);

Json::Reader json_reader;
if (!json_reader.parse(binary->get_data(), data)) {
throw ErrMsg("Could not decode JSON");
}
}

void DVIDNode::get_gray_slice(std::string datatype_instance, tuple start,
tuple sizes, tuple channels, DVIDGrayPtr& gray)
{
std::string volume;
retrieve_volume(datatype_instance, start, sizes, channels, volume);
gray = DVIDVoxels<unsigned char>::get_dvid_voxels(volume);
}

void DVIDNode::get_label_slice(std::string datatype_instance, tuple start,
tuple sizes, tuple channels, DVIDLabelPtr& labels)
{
std::string volume;
retrieve_volume(datatype_instance, start, sizes, channels, volume);
labels = DVIDVoxels<unsigned long long>::get_dvid_voxels(volume);
}

void DVIDNode::write_label_slice(std::string datatype_instance, tuple start,
tuple sizes, tuple channels, BinaryDataPtr data)
{
client::request requestobj(construct_volume_uri(
datatype_instance, start, sizes, channels));
requestobj << header("Connection", "close");
client request_client;
client::response respdata = request_client.post(requestobj,
"application/octet-stream", data->get_data());
int status_code = status(respdata);
if (status_code != 200) {
throw DVIDException(body(respdata), status_code);
}
}

std::string DVIDNode::construct_volume_uri(std::string datatype_inst, tuple start, tuple sizes, tuple channels)
{
std::string uri = web_addr.get_uri_root() + "node/" + uuid + "/"
+ datatype_inst + "/raw/";

if (start.size() < 3) {
throw ErrMsg("libdvid does not support 2D datatype instances");
}
if (channels.size() == 0) {
throw ErrMsg("must specify more than one channel");
}
if (sizes.size() != channels.size()) {
throw ErrMsg("number of size dimensions does not match the number of channels");
}
stringstream sstr;
sstr << uri;
sstr << channels[0];

// retrieve at least a 3D volume
set<int> used_channels;
for (int i = 0; i < channels.size(); ++i) {
used_channels.insert(channels[i]);
}
int channel_id = 0;
for (int i = channels.size(); i < 3; ++i) {
while (used_channels.find(channel_id) != used_channels.end()) {
++channel_id;
}
channels.push_back(channel_id);
}

for (int i = 1; i < channels.size(); ++i) {
sstr << "_" << channels[i];
}

// retrieve at least a 3D volume
for (int i = sizes.size(); i < 3; ++i) {
sizes.push_back(1);
}
sstr << "/" << sizes[0];
for (int i = 1; i < sizes.size(); ++i) {
sstr << "_" << sizes[i];
}
sstr << "/" << start[0];
for (int i = 1; i < start.size(); ++i) {
sstr << "_" << start[i];
}

return sstr.str();
}

void DVIDNode::retrieve_volume(std::string datatype_inst, tuple start, tuple sizes, tuple channels, std::string& volume)
{
client::request requestobj(construct_volume_uri(datatype_inst, start, sizes, channels));
requestobj << header("Connection", "close");
client request_client;
client::response respdata = request_client.get(requestobj);
int status_code = status(respdata);
if (status_code != 200) {
throw DVIDException(body(respdata), status_code);
}
volume = body(respdata);
}

}

Loading

0 comments on commit ed4308d

Please sign in to comment.