aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--gnunet-build/packages/gnunet/gnunet/files/gnunet-svn-36045-all.patch723
-rw-r--r--src/cljs/gnunet_web/filesharing.cljs19
-rw-r--r--src/hl/index.cljs.hl46
4 files changed, 757 insertions, 33 deletions
diff --git a/README.md b/README.md
index 0631c5b..edbbc8a 100644
--- a/README.md
+++ b/README.md
@@ -24,8 +24,6 @@ Roadmap
* Publish.
* The user can only select one file at a time.
* No directory support.
- * Needs a GNUnet API change to access the File object piecewise instead
- of loading the entire thing into RAM.
* Download.
* No directory support.
* Needs indexedDB support to store the file piecewise instead of
diff --git a/gnunet-build/packages/gnunet/gnunet/files/gnunet-svn-36045-all.patch b/gnunet-build/packages/gnunet/gnunet/files/gnunet-svn-36045-all.patch
index b4b59d0..d49b987 100644
--- a/gnunet-build/packages/gnunet/gnunet/files/gnunet-svn-36045-all.patch
+++ b/gnunet-build/packages/gnunet/gnunet/files/gnunet-svn-36045-all.patch
@@ -105,6 +105,729 @@ Index: gnunet-svn-36045/src/dns/Makefile.am
lib_LTLIBRARIES = \
libgnunetdnsparser.la \
libgnunetdnsstub.la \
+Index: gnunet-svn-36045/src/fs/fs_api.c
+===================================================================
+--- gnunet-svn-36045/src/fs/fs_api.c (revision 36045)
++++ gnunet-svn-36045/src/fs/fs_api.c (working copy)
+@@ -448,19 +448,22 @@
+ * to provide less data unless there is an error;
+ * a value of "0" will be used at the end to allow
+ * the reader to clean up its internal state
+- * @param buf where the reader should write the data
+- * @param emsg location for the reader to store an error message
+- * @return number of bytes written, usually @a max, 0 on error
++ * @param cont continuation to call with a pointer to the read bytes or an
++ * error message
++ * @param cont_cls closure to pass to the continuation
++ * @return GNUNET_SYSERR if cont will not be called, GNUNET_OK otherwise
+ */
+-size_t
++int
+ GNUNET_FS_data_reader_file_ (void *cls,
+ uint64_t offset,
+ size_t max,
+- void *buf,
+- char **emsg)
++ GNUNET_FS_ReaderContinuation cont,
++ void *cont_cls)
+ {
+ struct FileInfo *fi = cls;
+ ssize_t ret;
++ char **emsg = NULL;
++ char buf[max];
+
+ if (UINT64_MAX == offset)
+ {
+@@ -469,7 +472,7 @@
+ GNUNET_DISK_file_close (fi->fd);
+ fi->fd = NULL;
+ }
+- return 0;
++ return GNUNET_SYSERR;
+ }
+ if (0 == max)
+ {
+@@ -477,7 +480,7 @@
+ GNUNET_DISK_file_close (fi->fd);
+ GNUNET_free (fi->filename);
+ GNUNET_free (fi);
+- return 0;
++ return GNUNET_SYSERR;
+ }
+ if (NULL == fi->fd)
+ {
+@@ -491,7 +494,9 @@
+ _("Could not open file `%s': %s"),
+ fi->filename,
+ STRERROR (errno));
+- return 0;
++ if (cont)
++ cont (cont_cls, NULL, max, *emsg);
++ return GNUNET_OK;
+ }
+ }
+ if ( (GNUNET_SYSERR ==
+@@ -502,7 +507,9 @@
+ _("Could not read file `%s': %s"),
+ fi->filename,
+ STRERROR (errno));
+- return 0;
++ if (cont)
++ cont (cont_cls, NULL, max, *emsg);
++ return GNUNET_OK;
+ }
+ if (ret != max)
+ {
+@@ -509,9 +516,13 @@
+ GNUNET_asprintf (emsg,
+ _("Short read reading from file `%s'!"),
+ fi->filename);
+- return 0;
++ if (cont)
++ cont (cont_cls, NULL, max, *emsg);
++ return GNUNET_OK;
+ }
+- return max;
++ if (cont)
++ cont (cont_cls, buf, max, NULL);
++ return GNUNET_OK;
+ }
+
+
+@@ -553,28 +564,30 @@
+ * to provide less data unless there is an error;
+ * a value of "0" will be used at the end to allow
+ * the reader to clean up its internal state
+- * @param buf where the reader should write the data
+- * @param emsg location for the reader to store an error message
+- * @return number of bytes written, usually @a max, 0 on error
++ * @param cont continuation to call with a pointer to the read bytes or an
++ * error message
++ * @param cont_cls closure to pass to the continuation
++ * @return GNUNET_SYSERR if cont will not be called, GNUNET_OK otherwise
+ */
+-size_t
++int
+ GNUNET_FS_data_reader_copy_ (void *cls,
+ uint64_t offset,
+ size_t max,
+- void *buf,
+- char **emsg)
++ GNUNET_FS_ReaderContinuation cont,
++ void *cont_cls)
+ {
+ char *data = cls;
+
+ if (UINT64_MAX == offset)
+- return 0;
++ return GNUNET_SYSERR;
+ if (0 == max)
+ {
+ GNUNET_free_non_null (data);
+- return 0;
++ return GNUNET_SYSERR;
+ }
+- memcpy (buf, &data[offset], max);
+- return max;
++ if (cont)
++ cont (cont_cls, &data[offset], max, NULL);
++ return GNUNET_OK;
+ }
+
+
+@@ -1242,43 +1255,6 @@
+
+
+ /**
+- * Copy all of the data from the reader to the write handle.
+- *
+- * @param wh write handle
+- * @param fi file with reader
+- * @return #GNUNET_OK on success
+- */
+-static int
+-copy_from_reader (struct GNUNET_BIO_WriteHandle *wh,
+- struct GNUNET_FS_FileInformation *fi)
+-{
+- char buf[32 * 1024];
+- uint64_t off;
+- size_t ret;
+- size_t left;
+- char *emsg;
+-
+- emsg = NULL;
+- off = 0;
+- while (off < fi->data.file.file_size)
+- {
+- left = GNUNET_MIN (sizeof (buf), fi->data.file.file_size - off);
+- ret =
+- fi->data.file.reader (fi->data.file.reader_cls, off, left, buf, &emsg);
+- if (0 == ret)
+- {
+- GNUNET_free (emsg);
+- return GNUNET_SYSERR;
+- }
+- if (GNUNET_OK != GNUNET_BIO_write (wh, buf, ret))
+- return GNUNET_SYSERR;
+- off += ret;
+- }
+- return GNUNET_OK;
+-}
+-
+-
+-/**
+ * Create a temporary file on disk to store the current
+ * state of @a fi in.
+ *
+@@ -1362,7 +1338,6 @@
+ goto cleanup;
+ }
+ if ((GNUNET_NO == fi->is_published) && (NULL == fi->filename))
+- if (GNUNET_OK != copy_from_reader (wh, fi))
+ {
+ GNUNET_break (0);
+ goto cleanup;
+Index: gnunet-svn-36045/src/fs/fs_api.h
+===================================================================
+--- gnunet-svn-36045/src/fs/fs_api.h (revision 36045)
++++ gnunet-svn-36045/src/fs/fs_api.h (working copy)
+@@ -686,16 +686,17 @@
+ * to provide less data unless there is an error;
+ * a value of "0" will be used at the end to allow
+ * the reader to clean up its internal state
+- * @param buf where the reader should write the data
+- * @param emsg location for the reader to store an error message
+- * @return number of bytes written, usually "max", 0 on error
++ * @param cont continuation to call with a pointer to the read bytes or an
++ * error message
++ * @param cont_cls closure to pass to the continuation
++ * @return GNUNET_SYSERR if cont will not be called, GNUNET_OK otherwise
+ */
+-size_t
++int
+ GNUNET_FS_data_reader_file_ (void *cls,
+ uint64_t offset,
+ size_t max,
+- void *buf,
+- char **emsg);
++ GNUNET_FS_ReaderContinuation cont,
++ void *cont_cls);
+
+
+ /**
+@@ -721,16 +722,17 @@
+ * to provide less data unless there is an error;
+ * a value of "0" will be used at the end to allow
+ * the reader to clean up its internal state
+- * @param buf where the reader should write the data
+- * @param emsg location for the reader to store an error message
+- * @return number of bytes written, usually @a max, 0 on error
++ * @param cont continuation to call with a pointer to the read bytes or an
++ * error message
++ * @param cont_cls closure to pass to the continuation
++ * @return GNUNET_SYSERR if cont will not be called, GNUNET_OK otherwise
+ */
+-size_t
++int
+ GNUNET_FS_data_reader_copy_ (void *cls,
+ uint64_t offset,
+ size_t max,
+- void *buf,
+- char **emsg);
++ GNUNET_FS_ReaderContinuation cont,
++ void *cont_cls);
+
+
+ /**
+Index: gnunet-svn-36045/src/fs/fs_download.c
+===================================================================
+--- gnunet-svn-36045/src/fs/fs_download.c (revision 36045)
++++ gnunet-svn-36045/src/fs/fs_download.c (working copy)
+@@ -1820,33 +1820,36 @@
+ * @param offset identifies which block to get
+ * @param max (maximum) number of bytes to get; returning
+ * fewer will also cause errors
+- * @param buf where to copy the plaintext buffer
+- * @param emsg location to store an error message (on error)
+- * @return number of bytes copied to buf, 0 on error
++ * @param cont continuation to call with a pointer to the read bytes or an
++ * error message
++ * @param cont_cls closure to pass to the continuation
++ * @return GNUNET_SYSERR if cont will not be called, GNUNET_OK otherwise
+ */
+-static size_t
+-fh_reader (void *cls, uint64_t offset, size_t max, void *buf, char **emsg)
++static int
++fh_reader (void *cls, uint64_t offset, size_t max,
++ GNUNET_FS_ReaderContinuation cont, void *cont_cls)
+ {
+ struct GNUNET_FS_DownloadContext *dc = cls;
+ struct GNUNET_DISK_FileHandle *fh = dc->rfh;
+ ssize_t ret;
++ char buf[max];
+
+- if (NULL != emsg)
+- *emsg = NULL;
+ if (offset != GNUNET_DISK_file_seek (fh, offset, GNUNET_DISK_SEEK_SET))
+ {
+- if (NULL != emsg)
+- *emsg = GNUNET_strdup (strerror (errno));
+- return 0;
++ if (cont)
++ cont (cont_cls, NULL, max, GNUNET_strdup (strerror (errno)));
++ return GNUNET_OK;
+ }
+ ret = GNUNET_DISK_file_read (fh, buf, max);
+ if (ret < 0)
+ {
+- if (NULL != emsg)
+- *emsg = GNUNET_strdup (strerror (errno));
+- return 0;
++ if (cont)
++ cont (cont_cls, NULL, max, GNUNET_strdup (strerror (errno)));
++ return GNUNET_OK;
+ }
+- return ret;
++ if (cont)
++ cont (cont_cls, buf, max, NULL);
++ return GNUNET_OK;
+ }
+
+
+Index: gnunet-svn-36045/src/fs/fs_publish.c
+===================================================================
+--- gnunet-svn-36045/src/fs/fs_publish.c (revision 36045)
++++ gnunet-svn-36045/src/fs/fs_publish.c (working copy)
+@@ -366,24 +366,24 @@
+ * @param emsg location to store an error message (on error)
+ * @return number of bytes copied to buf, 0 on error
+ */
+-static size_t
++static int
+ block_reader (void *cls,
+ uint64_t offset,
+ size_t max,
+- void *buf,
+- char **emsg)
++ GNUNET_FS_ReaderContinuation cont,
++ void *cont_cls)
+ {
+ struct GNUNET_FS_PublishContext *pc = cls;
+ struct GNUNET_FS_FileInformation *p;
+ const char *dd;
+- size_t pt_size;
+
+ p = pc->fi_pos;
+ if (GNUNET_YES == p->is_directory)
+ {
+- pt_size = GNUNET_MIN (max, p->data.dir.dir_size - offset);
+ dd = p->data.dir.dir_data;
+- memcpy (buf, &dd[offset], pt_size);
++ if (cont)
++ cont (cont_cls, &dd[offset], max, NULL);
++ return GNUNET_OK;
+ }
+ else
+ {
+@@ -394,18 +394,11 @@
+ /* force closing the file to avoid keeping too many files open */
+ p->data.file.reader (p->data.file.reader_cls, offset, 0, NULL, NULL);
+ }
+- return 0;
++ return GNUNET_SYSERR; /* return value ignored in this case */
+ }
+- pt_size = GNUNET_MIN (max, p->data.file.file_size - offset);
+- if (0 == pt_size)
+- return 0; /* calling reader with pt_size==0
+- * might free buf, so don't! */
+- if (pt_size !=
+- p->data.file.reader (p->data.file.reader_cls, offset, pt_size, buf,
+- emsg))
+- return 0;
++ return p->data.file.reader (p->data.file.reader_cls, offset, max,
++ cont, cont_cls);
+ }
+- return pt_size;
+ }
+
+
+@@ -615,7 +608,6 @@
+ publish_content (struct GNUNET_FS_PublishContext *pc)
+ {
+ struct GNUNET_FS_FileInformation *p;
+- char *emsg;
+ struct GNUNET_FS_DirectoryBuilder *db;
+ struct GNUNET_FS_FileInformation *dirpos;
+ void *raw_data;
+@@ -640,22 +632,6 @@
+ else
+ {
+ raw_data = NULL;
+- if ((dirpos->data.file.file_size < MAX_INLINE_SIZE) &&
+- (dirpos->data.file.file_size > 0))
+- {
+- raw_data = GNUNET_malloc (dirpos->data.file.file_size);
+- emsg = NULL;
+- if (dirpos->data.file.file_size !=
+- dirpos->data.file.reader (dirpos->data.file.reader_cls, 0,
+- dirpos->data.file.file_size, raw_data,
+- &emsg))
+- {
+- GNUNET_free_non_null (emsg);
+- GNUNET_free (raw_data);
+- raw_data = NULL;
+- }
+- dirpos->data.file.reader (dirpos->data.file.reader_cls, UINT64_MAX, 0, 0, NULL);
+- }
+ }
+ GNUNET_FS_directory_builder_add (db, dirpos->chk_uri, dirpos->meta,
+ raw_data);
+Index: gnunet-svn-36045/src/fs/fs_test_lib.c
+===================================================================
+--- gnunet-svn-36045/src/fs/fs_test_lib.c (revision 36045)
++++ gnunet-svn-36045/src/fs/fs_test_lib.c (working copy)
+@@ -275,26 +275,23 @@
+ * @param cls pointer to uint32_t with publishing seed
+ * @param offset offset to generate data for
+ * @param max maximum number of bytes to generate
+- * @param buf where to write generated data
+- * @param emsg where to store error message (unused)
+- * @return number of bytes written to buf
++ * @param cont continuation to call with a pointer to the read bytes or an
++ * error message
++ * @param cont_cls closure to pass to the continuation
++ * @return GNUNET_SYSERR if cont will not be called, GNUNET_OK otherwise
+ */
+-static size_t
++static int
+ file_generator (void *cls,
+ uint64_t offset,
+ size_t max,
+- void *buf,
+- char **emsg)
++ GNUNET_FS_ReaderContinuation cont,
++ void *cont_cls)
+ {
+ uint32_t *publish_seed = cls;
+ uint64_t pos;
+- uint8_t *cbuf = buf;
++ uint8_t cbuf[max];
+ int mod;
+
+- if (emsg != NULL)
+- *emsg = NULL;
+- if (buf == NULL)
+- return 0;
+ for (pos = 0; pos < 8; pos++)
+ cbuf[pos] = (uint8_t) (offset >> pos * 8);
+ for (pos = 8; pos < max; pos++)
+@@ -304,7 +301,9 @@
+ mod = 1;
+ cbuf[pos] = (uint8_t) ((offset * (*publish_seed)) % mod);
+ }
+- return max;
++ if (cont)
++ cont (cont_cls, cbuf, max, NULL);
++ return GNUNET_OK;
+ }
+
+
+@@ -348,6 +347,24 @@
+
+
+ /**
++ * Continuation for GNUNET_FS_DataReader
++ */
++static void
++disk_write_cont (void *cls,
++ const void *pt_block,
++ uint16_t pt_size,
++ char *emsg)
++{
++ struct GNUNET_DISK_FileHandle *fh = cls;
++
++ GNUNET_assert (NULL != fh);
++ GNUNET_assert (NULL != pt_block);
++ GNUNET_assert (NULL == emsg);
++ GNUNET_assert (pt_size == GNUNET_DISK_file_write (fh, pt_block, pt_size));
++}
++
++
++/**
+ * Callback to be called when testbed has connected to the fs service
+ *
+ * @param cls the 'struct TestPublishOperation'
+@@ -365,9 +382,7 @@
+ struct TestPublishOperation *po = cls;
+ struct GNUNET_FS_FileInformation *fi;
+ struct GNUNET_DISK_FileHandle *fh;
+- char *em;
+ uint64_t off;
+- char buf[DBLOCK_SIZE];
+ size_t bsize;
+ struct GNUNET_FS_BlockOptions bo;
+
+@@ -399,11 +414,8 @@
+ off = 0;
+ while (off < po->size)
+ {
+- bsize = GNUNET_MIN (sizeof (buf), po->size - off);
+- emsg = NULL;
+- GNUNET_assert (bsize == file_generator (&po->publish_seed, off, bsize, buf, &em));
+- GNUNET_assert (em == NULL);
+- GNUNET_assert (bsize == GNUNET_DISK_file_write (fh, buf, bsize));
++ bsize = GNUNET_MIN (DBLOCK_SIZE, po->size - off);
++ GNUNET_assert (GNUNET_OK == file_generator (&po->publish_seed, off, bsize, disk_write_cont, fh));
+ off += bsize;
+ }
+ GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh));
+Index: gnunet-svn-36045/src/fs/fs_tree.c
+===================================================================
+--- gnunet-svn-36045/src/fs/fs_tree.c (revision 36045)
++++ gnunet-svn-36045/src/fs/fs_tree.c (working copy)
+@@ -322,59 +322,27 @@
+
+
+ /**
+- * Encrypt the next block of the file (and call proc and progress
+- * accordingly; or of course "cont" if we have already completed
+- * encoding of the entire file).
+- *
+- * @param te tree encoder to use
++ * Continuation for te->reader
+ */
+-void
+-GNUNET_FS_tree_encoder_next (struct GNUNET_FS_TreeEncoder *te)
++static void
++encrypt_block(void *cls,
++ const void *pt_block,
++ uint16_t pt_size,
++ char *emsg)
+ {
++ struct GNUNET_FS_TreeEncoder *te = cls;
+ struct ContentHashKey *mychk;
+- const void *pt_block;
+- uint16_t pt_size;
+- char iob[DBLOCK_SIZE];
+ char enc[DBLOCK_SIZE];
+ struct GNUNET_CRYPTO_SymmetricSessionKey sk;
+ struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
+ unsigned int off;
+
+- GNUNET_assert (GNUNET_NO == te->in_next);
+- te->in_next = GNUNET_YES;
+- if (te->chk_tree_depth == te->current_depth)
+- {
+- off = CHK_PER_INODE * (te->chk_tree_depth - 1);
+- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "TE done, reading CHK `%s' from %u\n",
+- GNUNET_h2s (&te->chk_tree[off].query), off);
+- te->uri = GNUNET_new (struct GNUNET_FS_Uri);
+- te->uri->type = GNUNET_FS_URI_CHK;
+- te->uri->data.chk.chk = te->chk_tree[off];
+- te->uri->data.chk.file_length = GNUNET_htonll (te->size);
++ if (NULL != emsg || NULL == pt_block) {
++ te->emsg = emsg;
+ te->in_next = GNUNET_NO;
+ te->cont (te->cls, NULL);
+ return;
+ }
+- if (0 == te->current_depth)
+- {
+- /* read DBLOCK */
+- pt_size = GNUNET_MIN (DBLOCK_SIZE, te->size - te->publish_offset);
+- if (pt_size !=
+- te->reader (te->cls, te->publish_offset, pt_size, iob, &te->emsg))
+- {
+- te->in_next = GNUNET_NO;
+- te->cont (te->cls, NULL);
+- return;
+- }
+- pt_block = iob;
+- }
+- else
+- {
+- pt_size =
+- GNUNET_FS_tree_compute_iblock_size (te->current_depth,
+- te->publish_offset);
+- pt_block = &te->chk_tree[(te->current_depth - 1) * CHK_PER_INODE];
+- }
+ off = compute_chk_offset (te->current_depth, te->publish_offset);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "TE is at offset %llu and depth %u with block size %u and target-CHK-offset %u\n",
+@@ -416,6 +384,58 @@
+
+
+ /**
++ * Encrypt the next block of the file (and call proc and progress
++ * accordingly; or of course "cont" if we have already completed
++ * encoding of the entire file).
++ *
++ * @param te tree encoder to use
++ */
++void
++GNUNET_FS_tree_encoder_next (struct GNUNET_FS_TreeEncoder *te)
++{
++ const void *pt_block;
++ uint16_t pt_size;
++ unsigned int off;
++
++ GNUNET_assert (GNUNET_NO == te->in_next);
++ te->in_next = GNUNET_YES;
++ if (te->chk_tree_depth == te->current_depth)
++ {
++ off = CHK_PER_INODE * (te->chk_tree_depth - 1);
++ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "TE done, reading CHK `%s' from %u\n",
++ GNUNET_h2s (&te->chk_tree[off].query), off);
++ te->uri = GNUNET_new (struct GNUNET_FS_Uri);
++ te->uri->type = GNUNET_FS_URI_CHK;
++ te->uri->data.chk.chk = te->chk_tree[off];
++ te->uri->data.chk.file_length = GNUNET_htonll (te->size);
++ te->in_next = GNUNET_NO;
++ te->cont (te->cls, NULL);
++ return;
++ }
++ if (0 == te->current_depth)
++ {
++ /* read DBLOCK */
++ pt_size = GNUNET_MIN (DBLOCK_SIZE, te->size - te->publish_offset);
++ if (GNUNET_OK !=
++ te->reader (te->cls, te->publish_offset, pt_size, &encrypt_block, te))
++ {
++ te->in_next = GNUNET_NO;
++ te->cont (te->cls, NULL);
++ return;
++ }
++ }
++ else
++ {
++ pt_size =
++ GNUNET_FS_tree_compute_iblock_size (te->current_depth,
++ te->publish_offset);
++ pt_block = &te->chk_tree[(te->current_depth - 1) * CHK_PER_INODE];
++ encrypt_block(te, pt_block, pt_size, NULL);
++ }
++}
++
++
++/**
+ * Get the resulting URI from the encoding.
+ *
+ * @param te the tree encoder to clean up
+@@ -446,7 +466,7 @@
+ {
+ if (NULL != te->reader)
+ {
+- (void) te->reader (te->cls, UINT64_MAX, 0, 0, NULL);
++ (void) te->reader (te->cls, UINT64_MAX, 0, NULL, NULL);
+ te->reader = NULL;
+ }
+ GNUNET_assert (GNUNET_NO == te->in_next);
+Index: gnunet-svn-36045/src/fs/fs_unindex.c
+===================================================================
+--- gnunet-svn-36045/src/fs/fs_unindex.c (revision 36045)
++++ gnunet-svn-36045/src/fs/fs_unindex.c (working copy)
+@@ -43,32 +43,37 @@
+ * @param offset identifies which block to get
+ * @param max (maximum) number of bytes to get; returning
+ * fewer will also cause errors
+- * @param buf where to copy the plaintext buffer
+- * @param emsg location to store an error message (on error)
+- * @return number of bytes copied to buf, 0 on error
++ * @param cont continuation to call with a pointer to the read bytes or an
++ * error message
++ * @param cont_cls closure to pass to the continuation
++ * @return GNUNET_SYSERR if cont will not be called, GNUNET_OK otherwise
+ */
+-static size_t
++static int
+ unindex_reader (void *cls,
+ uint64_t offset,
+ size_t max,
+- void *buf,
+- char **emsg)
++ GNUNET_FS_ReaderContinuation cont,
++ void *cont_cls)
+ {
+ struct GNUNET_FS_UnindexContext *uc = cls;
+- size_t pt_size;
++ char buf[max];
+
+- pt_size = GNUNET_MIN (max, uc->file_size - offset);
+ if (offset != GNUNET_DISK_file_seek (uc->fh, offset, GNUNET_DISK_SEEK_SET))
+ {
+- *emsg = GNUNET_strdup (_("Failed to find given position in file"));
+- return 0;
++ if (cont)
++ cont (cont_cls, NULL, max,
++ GNUNET_strdup (_("Failed to find given position in file")));
++ return GNUNET_OK;
+ }
+- if (pt_size != GNUNET_DISK_file_read (uc->fh, buf, pt_size))
++ if (max != GNUNET_DISK_file_read (uc->fh, buf, max))
+ {
+- *emsg = GNUNET_strdup (_("Failed to read file"));
+- return 0;
++ if (cont)
++ cont (cont_cls, NULL, max, GNUNET_strdup (_("Failed to read file")));
++ return GNUNET_OK;
+ }
+- return pt_size;
++ if (cont)
++ cont (cont_cls, buf, max, NULL);
++ return GNUNET_OK;
+ }
+
+
+Index: gnunet-svn-36045/src/include/gnunet_fs_service.h
+===================================================================
+--- gnunet-svn-36045/src/include/gnunet_fs_service.h (revision 36045)
++++ gnunet-svn-36045/src/include/gnunet_fs_service.h (working copy)
+@@ -1839,6 +1839,20 @@
+
+
+ /**
++ * Continuation for GNUNET_FS_DataReader
++ *
++ * @param cls closure
++ * @param pt_block pointer to bytes read by the reader
++ * @param pt_size the number of bytes read, must be equal to max
++ * @param emsg error message, NULL is there is no error
++ */
++typedef void (*GNUNET_FS_ReaderContinuation) (void *cls,
++ const void *pt_block,
++ uint16_t pt_size,
++ char *emsg);
++
++
++/**
+ * Function that provides data.
+ *
+ * @param cls closure
+@@ -1850,16 +1864,18 @@
+ * clean up the reader's state); in this case,
+ * a value of '0' for max should be ignored
+ * @param max maximum number of bytes that should be
+- * copied to buf; readers are not allowed
++ * passed to cont; readers are not allowed
+ * to provide less data unless there is an error;
+ * a value of "0" will be used at the end to allow
+ * the reader to clean up its internal state
+- * @param buf where the reader should write the data
+- * @param emsg location for the reader to store an error message
+- * @return number of bytes written, usually @a max, 0 on error
++ * @param cont continuation to call with a pointer to the read bytes or an
++ * error message
++ * @param cont_cls closure to pass to the continuation
++ * @return GNUNET_SYSERR if cont will not be called, GNUNET_OK otherwise
+ */
+-typedef size_t (*GNUNET_FS_DataReader) (void *cls, uint64_t offset, size_t max,
+- void *buf, char **emsg);
++typedef int (*GNUNET_FS_DataReader) (void *cls, uint64_t offset, size_t max,
++ GNUNET_FS_ReaderContinuation cont,
++ void *cont_cls);
+
+
+ /**
Index: gnunet-svn-36045/src/nat/Makefile.am
===================================================================
--- gnunet-svn-36045/src/nat/Makefile.am (revision 36045)
diff --git a/src/cljs/gnunet_web/filesharing.cljs b/src/cljs/gnunet_web/filesharing.cljs
index 65caf1f..0a6ad87 100644
--- a/src/cljs/gnunet_web/filesharing.cljs
+++ b/src/cljs/gnunet_web/filesharing.cljs
@@ -221,14 +221,23 @@
:callback-key callback-key}))
(defn publish-reader-callback
- [cls offset-lw offset-hw size buf emsg]
+ [cls offset-lw offset-hw size cont cont-cls]
(if (zero? size)
(do (unregister-object cls) 0)
(let [file (get-object cls)
offset (i64-to-real [offset-lw offset-hw])
- file-array (js/Uint8Array. file offset size)]
- (js/writeArrayToMemory file-array buf)
- size)))
+ reader (js/FileReader.)]
+ (set!
+ (.-onload reader)
+ (fn [e]
+ (let [result (js/Uint8Array. (.-result (.-target e)))]
+ (js/ccallFunc
+ (+++ (.getFuncWrapper js/Runtime cont "viiii"))
+ "void"
+ (array "number" "array" "number" "number")
+ (array cont-cls result size 0)))))
+ (.readAsArrayBuffer reader (.slice file offset (+ offset size)))
+ 1)))
(def publish-reader-callback-pointer
(+++ (.addFunction js/Runtime publish-reader-callback)))
@@ -240,7 +249,7 @@
(defn start-publish
[file keywords metadata block-options]
(let [file-key (register-object file)
- length (real-to-i64 (.-byteLength file))
+ length (real-to-i64 (.-size file))
ch (chan 1)
callback (fn [info] (go (>! ch info)))
callback-key (register-object callback)
diff --git a/src/hl/index.cljs.hl b/src/hl/index.cljs.hl
index 382eb65..e6fa6c4 100644
--- a/src/hl/index.cljs.hl
+++ b/src/hl/index.cljs.hl
@@ -118,32 +118,26 @@
(defn start-publish
[keywords metadata file anonymity state-cell progress-cell uri-cell]
- (let [reader (js/FileReader.)]
- (set!
- (.-onload reader)
- (fn [e]
- (let [publish (filesharing/start-publish
- (.-result (.-target e))
- keywords
- metadata
- {:expiration (+ (* 2 356.24 24 60 60 1000 1000) (now))
- :anonymity anonymity
- :priority 365
- :replication 1})]
- (go-loop
- []
- (when-let [info (<! (:ch publish))]
- (when (= :publish-start (:status info))
- (reset! state-cell :active))
- (when (= :publish-progress (:status info))
- (reset! progress-cell (if (zero? (:size info))
- 0
- (/ (:completed info) (:size info)))))
- (when (= :publish-completed (:status info))
- (reset! uri-cell (:uri info))
- (reset! state-cell :complete))
- (recur))))))
- (.readAsArrayBuffer reader file)))
+ (let [publish (filesharing/start-publish
+ file
+ keywords
+ metadata
+ {:expiration (+ (* 2 356.24 24 60 60 1000 1000) (now))
+ :anonymity anonymity
+ :priority 365
+ :replication 1})]
+ (go-loop []
+ (when-let [info (<! (:ch publish))]
+ (when (= :publish-start (:status info))
+ (reset! state-cell :active))
+ (when (= :publish-progress (:status info))
+ (reset! progress-cell (if (zero? (:size info))
+ 0
+ (/ (:completed info) (:size info)))))
+ (when (= :publish-completed (:status info))
+ (reset! uri-cell (:uri info))
+ (reset! state-cell :complete))
+ (recur)))))
(try
(def topology-worker (service/start-worker "topology"