Skip to content

Commit 94bf563

Browse files
committed
add entries iterator
1 parent ef21816 commit 94bf563

File tree

4 files changed

+228
-89
lines changed

4 files changed

+228
-89
lines changed

src/main/java/com/jsoniter/any/Any.java

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,29 @@ public Any wrap(Object obj) {
4141
JsonStream.registerNativeEncoder(ObjectAny.class, anyEncoder);
4242
}
4343

44+
public interface EntryIterator {
45+
boolean next();
46+
String key();
47+
Any value();
48+
}
49+
4450
protected final static Set<String> EMPTY_KEYS = Collections.unmodifiableSet(new HashSet<String>());
51+
protected final static EntryIterator EMPTY_ENTRIES_ITERATOR = new EntryIterator() {
52+
@Override
53+
public boolean next() {
54+
return false;
55+
}
56+
57+
@Override
58+
public String key() {
59+
throw new NoSuchElementException();
60+
}
61+
62+
@Override
63+
public Any value() {
64+
throw new NoSuchElementException();
65+
}
66+
};
4567
protected final static Iterator<Any> EMPTY_ITERATOR = new Iterator<Any>() {
4668
@Override
4769
public void remove() {
@@ -55,7 +77,7 @@ public boolean hasNext() {
5577

5678
@Override
5779
public Any next() {
58-
throw new UnsupportedOperationException();
80+
throw new NoSuchElementException();
5981
}
6082
};
6183

@@ -201,14 +223,16 @@ public int size() {
201223
}
202224

203225
public Set<String> keys() {
204-
return LazyAny.EMPTY_KEYS;
226+
return EMPTY_KEYS;
205227
}
206228

207229
@Override
208230
public Iterator<Any> iterator() {
209-
return LazyAny.EMPTY_ITERATOR;
231+
return EMPTY_ITERATOR;
210232
}
211233

234+
public EntryIterator entries() { return EMPTY_ENTRIES_ITERATOR; }
235+
212236
public Any get(int index) {
213237
return null;
214238
}

src/main/java/com/jsoniter/any/ArrayLazyAny.java

Lines changed: 63 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public Iterator<Any> iterator() {
4848
if (lastParsedPos == tail) {
4949
return cache.iterator();
5050
} else {
51-
return new LazyIterator(new JsonIterator());
51+
return new LazyIterator();
5252
}
5353
}
5454

@@ -89,46 +89,87 @@ private void fillCache() {
8989
if (lastParsedPos == tail) {
9090
return;
9191
}
92-
LazyIterator iter = new LazyIterator(JsonIterator.tlsIter.get());
93-
while (iter.hasNext()) {
94-
// cache will be filled in the process
95-
iter.next();
92+
if (cache == null) {
93+
cache = new ArrayList<Any>(4);
94+
}
95+
try {
96+
JsonIterator iter = JsonIterator.tlsIter.get();
97+
if (lastParsedPos == head) {
98+
iter.reset(data, lastParsedPos, tail);
99+
if (!CodegenAccess.readArrayStart(iter)) {
100+
lastParsedPos = tail;
101+
return;
102+
}
103+
cache.add(iter.readAny());
104+
}
105+
while (CodegenAccess.nextToken(iter) == ',') {
106+
cache.add(iter.readAny());
107+
}
108+
lastParsedPos = tail;
109+
} catch (IOException e) {
110+
throw new JsonException(e);
96111
}
97112
}
98113

99114
private Any fillCache(int target) {
100115
if (lastParsedPos == tail) {
101116
return cache.get(target);
102117
}
103-
int i = 0;
104-
LazyIterator iter = new LazyIterator(JsonIterator.tlsIter.get());
105-
while (iter.hasNext()) {
106-
Any element = iter.next();
107-
if (i == target) {
108-
return element;
118+
if (cache == null) {
119+
cache = new ArrayList<Any>(4);
120+
}
121+
int i = cache.size();
122+
if (target < i) {
123+
return cache.get(i);
124+
}
125+
try {
126+
JsonIterator iter = JsonIterator.tlsIter.get();
127+
if (lastParsedPos == head) {
128+
iter.reset(data, lastParsedPos, tail);
129+
if (!CodegenAccess.readArrayStart(iter)) {
130+
lastParsedPos = tail;
131+
return null;
132+
}
133+
Any element = iter.readAny();
134+
cache.add(element);
135+
if (target == 0) {
136+
lastParsedPos = CodegenAccess.head(iter);
137+
return element;
138+
}
139+
}
140+
while (CodegenAccess.nextToken(iter) == ',') {
141+
Any element = iter.readAny();
142+
cache.add(element);
143+
if (i++ == target) {
144+
lastParsedPos = CodegenAccess.head(iter);
145+
return element;
146+
}
109147
}
110-
i++;
148+
lastParsedPos = tail;
149+
} catch (IOException e) {
150+
throw new JsonException(e);
111151
}
112-
throw new IndexOutOfBoundsException();
152+
return null;
113153
}
114154

115155
private class LazyIterator implements Iterator<Any> {
116156

117-
private JsonIterator jsonIter;
118157
private final int cacheSize;
119158
private int cachePos;
120159

121-
public LazyIterator(JsonIterator jsonIter) {
160+
public LazyIterator() {
122161
try {
123-
if (jsonIter != null) {
124-
this.jsonIter = jsonIter;
125-
this.jsonIter.reset(data, lastParsedPos, tail);
126-
}
127162
if (cache == null) {
128163
cache = new ArrayList<Any>(4);
129164
}
130165
if (lastParsedPos == head) {
131-
readHead(jsonIter);
166+
JsonIterator iter = JsonIterator.tlsIter.get();
167+
iter.reset(data, lastParsedPos, tail);
168+
if (!CodegenAccess.readArrayStart(iter)) {
169+
lastParsedPos = tail;
170+
} else {
171+
lastParsedPos = CodegenAccess.head(iter);
172+
}
132173
}
133174
} catch (IOException e) {
134175
throw new JsonException(e);
@@ -137,16 +178,6 @@ public LazyIterator(JsonIterator jsonIter) {
137178
cachePos = 0;
138179
}
139180

140-
private void readHead(JsonIterator jsonIter) throws IOException {
141-
if (jsonIter == null) {
142-
jsonIter = JsonIterator.tlsIter.get();
143-
jsonIter.reset(data, lastParsedPos, tail);
144-
}
145-
if (!CodegenAccess.readArrayStart(jsonIter)) {
146-
lastParsedPos = tail;
147-
}
148-
}
149-
150181
@Override
151182
public void remove() {
152183
throw new UnsupportedOperationException();
@@ -170,11 +201,8 @@ private Any next_() throws IOException {
170201
if (cachePos != cacheSize) {
171202
return cache.get(cachePos++);
172203
}
173-
JsonIterator iter = jsonIter;
174-
if (iter == null) {
175-
iter = JsonIterator.tlsIter.get();
176-
iter.reset(data, lastParsedPos, tail);
177-
}
204+
JsonIterator iter = JsonIterator.tlsIter.get();
205+
iter.reset(data, lastParsedPos, tail);
178206
Any element = iter.readAny();
179207
cache.add(element);
180208
if (CodegenAccess.nextToken(iter) == ',') {

0 commit comments

Comments
 (0)