-
Notifications
You must be signed in to change notification settings - Fork 16
/
cell.cc
78 lines (72 loc) · 2.32 KB
/
cell.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include "cell.hpp"
#include "common.hpp"
// Avoid freeing shared memory
static void NullFreer(char *, void *) {}
const char *Cell::c_str() {
return cell_value.string_value.c_str();
}
Cell::operator double() {
if (type() != NUMBER_TYPE)
throw WrongPropertyType();
return cell_value.number_value;
}
Cell::Cell(const Cell &cell) {
cell_type = cell.cell_type;
switch (cell_type) {
case STRING_TYPE:
case BUFFER_TYPE:
new (&cell_value.string_value)(shared_string)(cell.cell_value.string_value);
break;
case NUMBER_TYPE:
cell_value.number_value = cell.cell_value.number_value;
break;
default:
throw WrongPropertyType();
}
}
v8::Local<v8::Value> Cell::GetValue() {
v8::Local<v8::Value> v;
switch (type()) {
case STRING_TYPE:
v = Nan::New<v8::String>(c_str()).ToLocalChecked();
break;
case BUFFER_TYPE:
v = Nan::NewBuffer(const_cast<char*>(c_str()), length(), NullFreer, NULL).ToLocalChecked();
break;
case NUMBER_TYPE:
v = Nan::New<v8::Number>(*this);
break;
default:
ostringstream error_stream;
error_stream << "Unknown cell data type " << dec << (int) type();
Nan::ThrowError(error_stream.str().c_str());
}
return v;
}
// Create a new cell to wrap the given value with, reset the given
// unique_ptr to that cell. Return the length of the data stored for
// the caller's accounting.
size_t Cell::SetValue(v8::Local<v8::Value> value, bip::managed_mapped_file *segment,
unique_ptr<Cell> &c, const Nan::PropertyCallbackInfo<v8::Value>& info) {
size_t length;
if (value->IsString()) {
v8::String::Utf8Value data UTF8VALUE(value);
length = data.length();
char_allocator allocer(segment->get_segment_manager());
c.reset(new Cell(string(*data).c_str(), allocer));
} else if (value->IsNumber()) {
length = sizeof(double);
c.reset(new Cell(Nan::To<double>(value).FromJust()));
} else if (value->IsArrayBufferView()) {
v8::Local<v8::Object> buf = Nan::To<v8::Object>(value).ToLocalChecked();
char* bufData = node::Buffer::Data(buf);
size_t bufLen = node::Buffer::Length(buf);
length = bufLen;
char_allocator allocer(segment->get_segment_manager());
c.reset(new Cell(bufData, bufLen, allocer));
} else {
Nan::ThrowError("Value must be a string, buffer, or number.");
return -1;
}
return length;
}