#include "gdal_common.hpp"
#include "gdal_field_defn.hpp"
#include "utils/field_types.hpp"
namespace node_gdal {
Nan::Persistent<FunctionTemplate> FieldDefn::constructor;
void FieldDefn::Initialize(Local<Object> target)
{
Nan::HandleScope scope;
Local<FunctionTemplate> lcons = Nan::New<FunctionTemplate>(FieldDefn::New);
lcons->InstanceTemplate()->SetInternalFieldCount(1);
lcons->SetClassName(Nan::New("FieldDefn").ToLocalChecked());
ATTR(lcons, "name", nameGetter, nameSetter);
ATTR(lcons, "type", typeGetter, typeSetter);
ATTR(lcons, "justification", justificationGetter, justificationSetter);
ATTR(lcons, "width", widthGetter, widthSetter);
ATTR(lcons, "precision", precisionGetter, precisionSetter);
ATTR(lcons, "ignored", ignoredGetter, ignoredSetter);
Nan::Set(target, Nan::New("FieldDefn").ToLocalChecked(), Nan::GetFunction(lcons).ToLocalChecked());
constructor.Reset(lcons);
}
FieldDefn::FieldDefn(OGRFieldDefn *def)
: Nan::ObjectWrap(),
this_(def),
owned_(false)
{
LOG("Created FieldDefn [%p]", def);
}
FieldDefn::FieldDefn()
: Nan::ObjectWrap(),
this_(0),
owned_(false)
{
}
FieldDefn::~FieldDefn()
{
if(this_){
LOG("Disposing FieldDefn [%p] (%s)", this_, owned_ ? "owned" : "unowned");
if(owned_) delete this_;
LOG("Disposed FieldDefn [%p]", this_);
this_ = NULL;
}
}
/**
* @constructor
* @class gdal.FieldDefn
* @param {String} name Field name
* @param {String} type Data type (see {{#crossLink "Constants (OFT)"}}OFT constants{{/crossLink}})
*/
NAN_METHOD(FieldDefn::New)
{
Nan::HandleScope scope;
if (!info.IsConstructCall()) {
Nan::ThrowError("Cannot call constructor as function, you need to use 'new' keyword");
return;
}
if (info[0]->IsExternal()) {
Local<External> ext = info[0].As<External>();
void* ptr = ext->Value();
FieldDefn *f = static_cast<FieldDefn *>(ptr);
f->Wrap(info.This());
info.GetReturnValue().Set(info.This());
return;
} else {
std::string field_name("");
std::string type_name("string");
NODE_ARG_STR(0, "field name", field_name);
NODE_ARG_STR(1, "field type", type_name);
int field_type = getFieldTypeByName(type_name);
if (field_type < 0) {
Nan::ThrowError("Unrecognized field type");
return;
}
FieldDefn* def = new FieldDefn(new OGRFieldDefn(field_name.c_str(), static_cast<OGRFieldType>(field_type)));
def->owned_ = true;
def->Wrap(info.This());
}
info.GetReturnValue().Set(info.This());
}
Local<Value> FieldDefn::New(OGRFieldDefn *def)
{
Nan::EscapableHandleScope scope;
return scope.Escape(FieldDefn::New(def, false));
}
Local<Value> FieldDefn::New(OGRFieldDefn *def, bool owned)
{
Nan::EscapableHandleScope scope;
if (!def) {
return scope.Escape(Nan::Null());
}
//make a copy of fielddefn owned by a featuredefn
// + no need to track when a featuredefn is destroyed
// + no need to throw errors when a method trys to modify an owned read-only fielddefn
// - is slower
if (!owned) {
def = new OGRFieldDefn(def);
}
FieldDefn *wrapped = new FieldDefn(def);
wrapped->owned_ = true;
v8::Local<v8::Value> ext = Nan::New<External>(wrapped);
v8::Local<v8::Object> obj = Nan::NewInstance(Nan::GetFunction(Nan::New(FieldDefn::constructor)).ToLocalChecked(), 1, &ext).ToLocalChecked();
return scope.Escape(obj);
}
NAN_METHOD(FieldDefn::toString)
{
Nan::HandleScope scope;
info.GetReturnValue().Set(Nan::New("FieldDefn").ToLocalChecked());
}
/**
* @attribute name
* @type {String}
*/
NAN_GETTER(FieldDefn::nameGetter)
{
Nan::HandleScope scope;
FieldDefn *def = Nan::ObjectWrap::Unwrap<FieldDefn>(info.This());
info.GetReturnValue().Set(SafeString::New(def->this_->GetNameRef()));
}
/**
* Data type (see {{#crossLink "Constants (OFT)"}}OFT constants{{/crossLink}})
*
* @attribute type
* @type {String}
*/
NAN_GETTER(FieldDefn::typeGetter)
{
Nan::HandleScope scope;
FieldDefn *def = Nan::ObjectWrap::Unwrap<FieldDefn>(info.This());
info.GetReturnValue().Set(SafeString::New(getFieldTypeName(def->this_->GetType())));
}
/**
* @attribute ignored
* @type {Boolean}
*/
NAN_GETTER(FieldDefn::ignoredGetter)
{
Nan::HandleScope scope;
FieldDefn *def = Nan::ObjectWrap::Unwrap<FieldDefn>(info.This());
info.GetReturnValue().Set(Nan::New<Boolean>(def->this_->IsIgnored()));
}
/**
* Field justification (see {{#crossLink "Constants (OJ)"}}OJ constants{{/crossLink}})
*
* @attribute justification
* @type {String}
*/
NAN_GETTER(FieldDefn::justificationGetter)
{
Nan::HandleScope scope;
FieldDefn *def = Nan::ObjectWrap::Unwrap<FieldDefn>(info.This());
OGRJustification justification = def->this_->GetJustify();
if (justification == OJRight) {
info.GetReturnValue().Set(Nan::New("Right").ToLocalChecked());
return;
}
if (justification == OJLeft) {
info.GetReturnValue().Set(Nan::New("Left").ToLocalChecked());
return;
}
info.GetReturnValue().Set(Nan::Undefined());
}
/**
* @attribute width
* @type {Integer}
*/
NAN_GETTER(FieldDefn::widthGetter)
{
Nan::HandleScope scope;
FieldDefn *def = Nan::ObjectWrap::Unwrap<FieldDefn>(info.This());
info.GetReturnValue().Set(Nan::New<Integer>(def->this_->GetWidth()));
}
/**
* @attribute precision
* @type {Integer}
*/
NAN_GETTER(FieldDefn::precisionGetter)
{
Nan::HandleScope scope;
FieldDefn *def = Nan::ObjectWrap::Unwrap<FieldDefn>(info.This());
info.GetReturnValue().Set(Nan::New<Integer>(def->this_->GetPrecision()));
}
NAN_SETTER(FieldDefn::nameSetter)
{
Nan::HandleScope scope;
FieldDefn *def = Nan::ObjectWrap::Unwrap<FieldDefn>(info.This());
if(!value->IsString()){
Nan::ThrowError("Name must be string");
return;
}
std::string name = *Nan::Utf8String(value);
def->this_->SetName(name.c_str());
}
NAN_SETTER(FieldDefn::typeSetter)
{
Nan::HandleScope scope;
FieldDefn *def = Nan::ObjectWrap::Unwrap<FieldDefn>(info.This());
if(!value->IsString()){
Nan::ThrowError("type must be a string");
return;
}
std::string name = *Nan::Utf8String(value);
int type = getFieldTypeByName(name.c_str());
if(type < 0){
Nan::ThrowError("Unrecognized field type");
} else {
def->this_->SetType(OGRFieldType(type));
}
}
NAN_SETTER(FieldDefn::justificationSetter)
{
Nan::HandleScope scope;
FieldDefn *def = Nan::ObjectWrap::Unwrap<FieldDefn>(info.This());
OGRJustification justification;
std::string str = *Nan::Utf8String(value);
if(value->IsString()){
if(str == "Left") {
justification = OJLeft;
} else if (str == "Right") {
justification = OJRight;
} else if (str == "Undefined") {
justification = OJUndefined;
} else {
Nan::ThrowError("Unrecognized justification");
return;
}
} else if (value->IsNull() || value->IsUndefined()){
justification = OJUndefined;
} else {
Nan::ThrowError("justification must be a string or undefined");
return;
}
def->this_->SetJustify(justification);
}
NAN_SETTER(FieldDefn::widthSetter)
{
Nan::HandleScope scope;
FieldDefn *def = Nan::ObjectWrap::Unwrap<FieldDefn>(info.This());
if(!value->IsInt32()){
Nan::ThrowError("width must be an integer");
return;
}
def->this_->SetWidth(Nan::To<int64_t>(value).ToChecked());
}
NAN_SETTER(FieldDefn::precisionSetter)
{
Nan::HandleScope scope;
FieldDefn *def = Nan::ObjectWrap::Unwrap<FieldDefn>(info.This());
if(!value->IsInt32()){
Nan::ThrowError("precision must be an integer");
return;
}
def->this_->SetPrecision(Nan::To<int64_t>(value).ToChecked());
}
NAN_SETTER(FieldDefn::ignoredSetter)
{
Nan::HandleScope scope;
FieldDefn *def = Nan::ObjectWrap::Unwrap<FieldDefn>(info.This());
if(!value->IsBoolean()){
Nan::ThrowError("ignored must be a boolean");
return;
}
def->this_->SetIgnored(Nan::To<int64_t>(value).ToChecked());
}
} // namespace node_gdal