/**
* Copyright (C) Zhang,Yuexiang (xfeep)
*
*/
package nginx.clojure.clj;
import static nginx.clojure.MiniConstants.DEFAULT_ENCODING;
import static nginx.clojure.MiniConstants.NGX_HTTP_CLOJURE_ARRAY_ELTS_OFFSET;
import static nginx.clojure.MiniConstants.NGX_HTTP_CLOJURE_PTR_SIZE;
import static nginx.clojure.MiniConstants.NGX_HTTP_CLOJURE_TEL_HASH_OFFSET;
import static nginx.clojure.MiniConstants.NGX_HTTP_CLOJURE_TEL_KEY_OFFSET;
import static nginx.clojure.MiniConstants.NGX_HTTP_CLOJURE_TEL_VALUE_OFFSET;
import static nginx.clojure.MiniConstants.NGX_OK;
import static nginx.clojure.NginxClojureRT.UNSAFE;
import nginx.clojure.ArrayHeaderHolder;
import nginx.clojure.NginxClojureRT;
import clojure.lang.ArraySeq;
import clojure.lang.ISeq;
import clojure.lang.RT;
public class SeqHeaderHolder extends ArrayHeaderHolder {
public SeqHeaderHolder(String name, long offset, long headersOffset) {
super(name, offset, headersOffset);
}
@Override
public void push(long h, long pool, Object v) {
long haddr = h + offset;
if (haddr == 0){
throw new RuntimeException("invalid address for set header array value " + v);
}
ISeq seq = null;
if (v instanceof String) {
String val = (String) v;
seq = ArraySeq.create(val);
}else if (v instanceof ISeq) {
seq = (ISeq) v;
}else {
seq = RT.seq(v);
}
int c = seq.count();
if (c == 0) {
return;
}
long lp = UNSAFE.getAddress(haddr + NGX_HTTP_CLOJURE_ARRAY_ELTS_OFFSET);
if (lp != 0) {
NginxClojureRT.ngx_array_destory(lp);
}
long code = NginxClojureRT.ngx_array_init(haddr, pool, c, NGX_HTTP_CLOJURE_PTR_SIZE);
if (code != NGX_OK) {
throw new RuntimeException("can not init ngx array for header, return code:" + code);
}
lp = NginxClojureRT.ngx_array_push_n(haddr, c);
if (lp == 0) {
throw new RuntimeException("can not push ngx array for header");
}
for (int i = 0; i < c; i++) {
String val = (String) seq.first();
seq = seq.next();
if (val != null) {
long p = NginxClojureRT.ngx_list_push(h + headersOffset);
if (p == 0) {
throw new RuntimeException("can not push ngx list for headers");
}
NginxClojureRT.pushNGXInt(p + NGX_HTTP_CLOJURE_TEL_HASH_OFFSET, 1);
NginxClojureRT.pushNGXString(p + NGX_HTTP_CLOJURE_TEL_KEY_OFFSET, name, DEFAULT_ENCODING, pool);
NginxClojureRT.pushNGXString(p + NGX_HTTP_CLOJURE_TEL_VALUE_OFFSET, val, DEFAULT_ENCODING, pool);
UNSAFE.putAddress(lp, p);
lp += NGX_HTTP_CLOJURE_PTR_SIZE;
}
}
}
@Override
public Object fetch(long h) {
Object v = super.fetch(h);
if (v != null && v.getClass().isArray()) {
return RT.seq(v);
}
return v;
}
}