@@ -238,6 +238,25 @@ static size_t StringOrBufferLength (napi_env env, napi_value value) {
238238 return size;
239239}
240240
241+ /* *
242+ * Takes a Buffer or string property 'name' from 'opts'.
243+ * Returns null if the property does not exist or is zero-length.
244+ */
245+ static std::string* RangeOption (napi_env env, napi_value opts, const char * name) {
246+ if (HasProperty (env, opts, name)) {
247+ napi_value value = GetProperty (env, opts, name);
248+
249+ if (StringOrBufferLength (env, value) > 0 ) {
250+ LD_STRING_OR_BUFFER_TO_COPY (env, value, to);
251+ std::string* result = new std::string (toCh_, toSz_);
252+ delete [] toCh_;
253+ return result;
254+ }
255+ }
256+
257+ return NULL ;
258+ }
259+
241260/* *
242261 * Calls a function.
243262 */
@@ -493,7 +512,7 @@ struct PriorityWorker : public BaseWorker {
493512struct Iterator {
494513 Iterator (Database* database,
495514 uint32_t id,
496- leveldb::Slice * start,
515+ std::string * start,
497516 std::string* end,
498517 bool reverse,
499518 bool keys,
@@ -540,32 +559,14 @@ struct Iterator {
540559 ~Iterator () {
541560 assert (ended_);
542561 ReleaseTarget ();
543- if (start_ != NULL ) {
544- // Special case for `start` option: it won't be
545- // freed up by any of the delete calls below.
546- if (!((lt_ != NULL && reverse_)
547- || (lte_ != NULL && reverse_)
548- || (gt_ != NULL && !reverse_)
549- || (gte_ != NULL && !reverse_))) {
550- delete [] start_->data ();
551- }
552- delete start_;
553- }
554- if (end_ != NULL ) {
555- delete end_;
556- }
557- if (lt_ != NULL ) {
558- delete lt_;
559- }
560- if (gt_ != NULL ) {
561- delete gt_;
562- }
563- if (lte_ != NULL ) {
564- delete lte_;
565- }
566- if (gte_ != NULL ) {
567- delete gte_;
568- }
562+
563+ if (start_ != NULL ) delete start_;
564+ if (end_ != NULL ) delete end_;
565+ if (lt_ != NULL ) delete lt_;
566+ if (gt_ != NULL ) delete gt_;
567+ if (lte_ != NULL ) delete lte_;
568+ if (gte_ != NULL ) delete gte_;
569+
569570 delete options_;
570571 }
571572
@@ -730,7 +731,7 @@ struct Iterator {
730731
731732 Database* database_;
732733 uint32_t id_;
733- leveldb::Slice * start_;
734+ std::string * start_;
734735 std::string* end_;
735736 bool reverse_;
736737 bool keys_;
@@ -1302,17 +1303,6 @@ static void FinalizeIterator (napi_env env, void* data, void* hint) {
13021303 }
13031304}
13041305
1305- #define CHECK_PROPERTY (name, code ) \
1306- if (HasProperty(env, options, #name)) { \
1307- napi_value value = GetProperty (env, options, #name); \
1308- if (IsString (env, value) || IsBuffer (env, value)) { \
1309- if (StringOrBufferLength (env, value) > 0 ) { \
1310- LD_STRING_OR_BUFFER_TO_COPY (env, value, _##name); \
1311- code; \
1312- } \
1313- } \
1314- } \
1315-
13161306/* *
13171307 * Create an iterator.
13181308 */
@@ -1331,84 +1321,18 @@ NAPI_METHOD(iterator_init) {
13311321 uint32_t highWaterMark = Uint32Property (env, options, " highWaterMark" ,
13321322 16 * 1024 );
13331323
1334- // TODO simplify and refactor the hideous code below
1335-
1336- leveldb::Slice* start = NULL ;
1337- char *startStr = NULL ;
1338- CHECK_PROPERTY (start, {
1339- start = new leveldb::Slice (_startCh_, _startSz_);
1340- startStr = _startCh_;
1341- });
1342-
1343- std::string* end = NULL ;
1344- CHECK_PROPERTY (end, {
1345- end = new std::string (_endCh_, _endSz_);
1346- delete [] _endCh_;
1347- });
1348-
1349- std::string* lt = NULL ;
1350- CHECK_PROPERTY (lt, {
1351- lt = new std::string (_ltCh_, _ltSz_);
1352- delete [] _ltCh_;
1353- if (reverse) {
1354- if (startStr != NULL ) {
1355- delete [] startStr;
1356- startStr = NULL ;
1357- }
1358- if (start != NULL ) {
1359- delete start;
1360- }
1361- start = new leveldb::Slice (lt->data (), lt->size ());
1362- }
1363- });
1364-
1365- std::string* lte = NULL ;
1366- CHECK_PROPERTY (lte, {
1367- lte = new std::string (_lteCh_, _lteSz_);
1368- delete [] _lteCh_;
1369- if (reverse) {
1370- if (startStr != NULL ) {
1371- delete [] startStr;
1372- startStr = NULL ;
1373- }
1374- if (start != NULL ) {
1375- delete start;
1376- }
1377- start = new leveldb::Slice (lte->data (), lte->size ());
1378- }
1379- });
1380-
1381- std::string* gt = NULL ;
1382- CHECK_PROPERTY (gt, {
1383- gt = new std::string (_gtCh_, _gtSz_);
1384- delete [] _gtCh_;
1385- if (!reverse) {
1386- if (startStr != NULL ) {
1387- delete [] startStr;
1388- startStr = NULL ;
1389- }
1390- if (start != NULL ) {
1391- delete start;
1392- }
1393- start = new leveldb::Slice (gt->data (), gt->size ());
1394- }
1395- });
1396-
1397- std::string* gte = NULL ;
1398- CHECK_PROPERTY (gte, {
1399- gte = new std::string (_gteCh_, _gteSz_);
1400- delete [] _gteCh_;
1401- if (!reverse) {
1402- if (startStr != NULL ) {
1403- delete [] startStr;
1404- startStr = NULL ;
1405- }
1406- if (start != NULL ) {
1407- delete start;
1408- }
1409- start = new leveldb::Slice (gte->data (), gte->size ());
1410- }
1411- });
1324+ std::string* start = NULL ;
1325+ std::string* end = RangeOption (env, options, " end" );
1326+ std::string* lt = RangeOption (env, options, " lt" );
1327+ std::string* lte = RangeOption (env, options, " lte" );
1328+ std::string* gt = RangeOption (env, options, " gt" );
1329+ std::string* gte = RangeOption (env, options, " gte" );
1330+
1331+ if (!reverse && gte != NULL ) start = new std::string (*gte);
1332+ else if (!reverse && gt != NULL ) start = new std::string (*gt);
1333+ else if (reverse && lte != NULL ) start = new std::string (*lte);
1334+ else if (reverse && lt != NULL ) start = new std::string (*lt);
1335+ else start = RangeOption (env, options, " start" );
14121336
14131337 uint32_t id = database->currentIteratorId_ ++;
14141338 Iterator* iterator = new Iterator (database, id, start, end, reverse, keys,
0 commit comments