int buildTOC(miniexp_t expr, list * myList, int level, JNIEnv * env, jclass olClass, jmethodID ctor) { while(miniexp_consp(expr)) { miniexp_t s = miniexp_car(expr); expr = miniexp_cdr(expr); if (miniexp_consp(s) && miniexp_consp(miniexp_cdr(s)) && miniexp_stringp(miniexp_car(s)) && miniexp_stringp(miniexp_cadr(s)) ) { // fill item const char *name = miniexp_to_str(miniexp_car(s)); const char *page = miniexp_to_str(miniexp_cadr(s)); //starts with # int pageno = -1; if (page[0] == '#') { pageno = ddjvu_document_search_pageno(doc, &page[1]); } if (pageno < 0) { LOGI("Page %s", page); } if (name == NULL) {return -1;} OutlineItem * element = (OutlineItem *) malloc(sizeof(OutlineItem)); element->title = name; element->page = pageno; element->level = level; list_item * next = (list_item *) malloc(sizeof(list_item)); next->item = element; next->next = NULL; myList->tail->next = next; myList->tail = next; // recursion buildTOC(miniexp_cddr(s), myList, level+1, env, olClass, ctor); } } return 0; }
JNIEXPORT jobjectArray JNICALL Java_universe_constellation_orion_viewer_djvu_DjvuDocument_getOutline(JNIEnv * env, jobject thiz) { miniexp_t outline = ddjvu_document_get_outline(doc); if (outline == miniexp_dummy || outline == NULL) { return NULL; } if (!miniexp_consp(outline) || miniexp_car(outline) != miniexp_symbol("bookmarks")) { LOGI("Outlines is empty"); } list_item * root = (list_item *) malloc(sizeof(list_item)); root->next = NULL; list * myList = (list *) malloc(sizeof(list)); myList->head = root; myList->tail = root; jclass olClass; jmethodID ctor; olClass = (*env)->FindClass(env, "universe/constellation/orion/viewer/outline/OutlineItem"); if (olClass == NULL) return NULL; ctor = (*env)->GetMethodID(env, olClass, "<init>", "(ILjava/lang/String;I)V"); if (ctor == NULL) return NULL; buildTOC(miniexp_cdr(outline), myList, 0, env, olClass, ctor); list_item * next = myList->head; int size = 0; while (next->next != NULL) { next = next->next; size++; } LOGI("Outline has %i entries", size); jobjectArray arr = (*env)->NewObjectArray(env, size, olClass, NULL); if (arr == NULL) { return NULL; } next = root->next; int pos = 0; while (next != NULL) { OutlineItem * item = next->item; jstring title = (*env)->NewStringUTF(env, item->title); //shift pageno to zero based jobject element = (*env)->NewObject(env, olClass, ctor, item->level, title, item->page - 1); (*env)->SetObjectArrayElement(env, arr, pos, element); (*env)->DeleteLocalRef(env, title); (*env)->DeleteLocalRef(env, element); free(item); list_item * next2 = next->next; free(next); next = next2; pos++; } free(root); return arr; }