@@ -224,6 +224,25 @@ static size_t StringOrBufferLength (napi_env env, napi_value value) {
224224 return size;
225225}
226226
227+ /* *
228+ * Takes a Buffer or string property 'name' from 'opts'.
229+ * Returns null if the property does not exist or is zero-length.
230+ */
231+ static std::string* RangeOption (napi_env env, napi_value opts, const char * name) {
232+ if (HasProperty (env, opts, name)) {
233+ napi_value value = GetProperty (env, opts, name);
234+
235+ if (StringOrBufferLength (env, value) > 0 ) {
236+ LD_STRING_OR_BUFFER_TO_COPY (env, value, to);
237+ std::string* result = new std::string (toCh_, toSz_);
238+ delete [] toCh_;
239+ return result;
240+ }
241+ }
242+
243+ return NULL ;
244+ }
245+
227246/* *
228247 * Calls a function.
229248 */
@@ -481,7 +500,7 @@ struct PriorityWorker : public BaseWorker {
481500struct Iterator {
482501 Iterator (Database* database,
483502 uint32_t id,
484- leveldb::Slice * start,
503+ std::string * start,
485504 std::string* end,
486505 bool reverse,
487506 bool keys,
@@ -527,32 +546,14 @@ struct Iterator {
527546 ~Iterator () {
528547 assert (ended_);
529548 ReleaseTarget ();
530- if (start_ != NULL ) {
531- // Special case for `start` option: it won't be
532- // freed up by any of the delete calls below.
533- if (!((lt_ != NULL && reverse_)
534- || (lte_ != NULL && reverse_)
535- || (gt_ != NULL && !reverse_)
536- || (gte_ != NULL && !reverse_))) {
537- delete [] start_->data ();
538- }
539- delete start_;
540- }
541- if (end_ != NULL ) {
542- delete end_;
543- }
544- if (lt_ != NULL ) {
545- delete lt_;
546- }
547- if (gt_ != NULL ) {
548- delete gt_;
549- }
550- if (lte_ != NULL ) {
551- delete lte_;
552- }
553- if (gte_ != NULL ) {
554- delete gte_;
555- }
549+
550+ if (start_ != NULL ) delete start_;
551+ if (end_ != NULL ) delete end_;
552+ if (lt_ != NULL ) delete lt_;
553+ if (gt_ != NULL ) delete gt_;
554+ if (lte_ != NULL ) delete lte_;
555+ if (gte_ != NULL ) delete gte_;
556+
556557 delete options_;
557558 }
558559
@@ -717,7 +718,7 @@ struct Iterator {
717718
718719 Database* database_;
719720 uint32_t id_;
720- leveldb::Slice * start_;
721+ std::string * start_;
721722 std::string* end_;
722723 bool reverse_;
723724 bool keys_;
@@ -1240,17 +1241,6 @@ static void FinalizeIterator (napi_env env, void* data, void* hint) {
12401241 }
12411242}
12421243
1243- #define CHECK_PROPERTY (name, code ) \
1244- if (HasProperty(env, options, #name)) { \
1245- napi_value value = GetProperty (env, options, #name); \
1246- if (IsString (env, value) || IsBuffer (env, value)) { \
1247- if (StringOrBufferLength (env, value) > 0 ) { \
1248- LD_STRING_OR_BUFFER_TO_COPY (env, value, _##name); \
1249- code; \
1250- } \
1251- } \
1252- } \
1253-
12541244/* *
12551245 * Create an iterator.
12561246 */
@@ -1269,84 +1259,18 @@ NAPI_METHOD(iterator_init) {
12691259 uint32_t highWaterMark = Uint32Property (env, options, " highWaterMark" ,
12701260 16 * 1024 );
12711261
1272- // TODO simplify and refactor the hideous code below
1273-
1274- leveldb::Slice* start = NULL ;
1275- char *startStr = NULL ;
1276- CHECK_PROPERTY (start, {
1277- start = new leveldb::Slice (_startCh_, _startSz_);
1278- startStr = _startCh_;
1279- });
1280-
1281- std::string* end = NULL ;
1282- CHECK_PROPERTY (end, {
1283- end = new std::string (_endCh_, _endSz_);
1284- delete [] _endCh_;
1285- });
1286-
1287- std::string* lt = NULL ;
1288- CHECK_PROPERTY (lt, {
1289- lt = new std::string (_ltCh_, _ltSz_);
1290- delete [] _ltCh_;
1291- if (reverse) {
1292- if (startStr != NULL ) {
1293- delete [] startStr;
1294- startStr = NULL ;
1295- }
1296- if (start != NULL ) {
1297- delete start;
1298- }
1299- start = new leveldb::Slice (lt->data (), lt->size ());
1300- }
1301- });
1302-
1303- std::string* lte = NULL ;
1304- CHECK_PROPERTY (lte, {
1305- lte = new std::string (_lteCh_, _lteSz_);
1306- delete [] _lteCh_;
1307- if (reverse) {
1308- if (startStr != NULL ) {
1309- delete [] startStr;
1310- startStr = NULL ;
1311- }
1312- if (start != NULL ) {
1313- delete start;
1314- }
1315- start = new leveldb::Slice (lte->data (), lte->size ());
1316- }
1317- });
1318-
1319- std::string* gt = NULL ;
1320- CHECK_PROPERTY (gt, {
1321- gt = new std::string (_gtCh_, _gtSz_);
1322- delete [] _gtCh_;
1323- if (!reverse) {
1324- if (startStr != NULL ) {
1325- delete [] startStr;
1326- startStr = NULL ;
1327- }
1328- if (start != NULL ) {
1329- delete start;
1330- }
1331- start = new leveldb::Slice (gt->data (), gt->size ());
1332- }
1333- });
1334-
1335- std::string* gte = NULL ;
1336- CHECK_PROPERTY (gte, {
1337- gte = new std::string (_gteCh_, _gteSz_);
1338- delete [] _gteCh_;
1339- if (!reverse) {
1340- if (startStr != NULL ) {
1341- delete [] startStr;
1342- startStr = NULL ;
1343- }
1344- if (start != NULL ) {
1345- delete start;
1346- }
1347- start = new leveldb::Slice (gte->data (), gte->size ());
1348- }
1349- });
1262+ std::string* start = NULL ;
1263+ std::string* end = RangeOption (env, options, " end" );
1264+ std::string* lt = RangeOption (env, options, " lt" );
1265+ std::string* lte = RangeOption (env, options, " lte" );
1266+ std::string* gt = RangeOption (env, options, " gt" );
1267+ std::string* gte = RangeOption (env, options, " gte" );
1268+
1269+ if (!reverse && gte != NULL ) start = new std::string (*gte);
1270+ else if (!reverse && gt != NULL ) start = new std::string (*gt);
1271+ else if (reverse && lte != NULL ) start = new std::string (*lte);
1272+ else if (reverse && lt != NULL ) start = new std::string (*lt);
1273+ else start = RangeOption (env, options, " start" );
13501274
13511275 uint32_t id = database->currentIteratorId_ ++;
13521276 Iterator* iterator = new Iterator (database, id, start, end, reverse, keys,
0 commit comments