diff --git a/src/logger.c b/src/logger.c
index c547b6ffdfe840e63c85d2b04654843c50d50b62..8efd8904c46a5b2cfa753323d6078f1988ef744f 100644
--- a/src/logger.c
+++ b/src/logger.c
@@ -90,7 +90,7 @@ int logger_size(unsigned int mask) {
 /**
  * @brief Dump a #part to the log.
  *
- * @param part The #part to dump.
+ * @param p The #part to dump.
  * @param mask The mask of the data to dump.
  * @param offset Pointer to the offset of the previous log of this particle.
  * @param dump The #dump in which to log the particle data.
@@ -111,7 +111,7 @@ void logger_log_part(struct part *p, unsigned int mask, size_t *offset,
   char *buff = dump_get(dump, size, &offset_new);
 
   /* Write the header. */
-  uint64_t temp = (((uint64_t)(offset_new - *offset)) & 0xffffffffffffffL) |
+  uint64_t temp = (((uint64_t)(offset_new - *offset)) & 0xffffffffffffffULL) |
                   ((uint64_t)mask << 56);
   memcpy(buff, &temp, 8);
   buff += 8;
@@ -171,7 +171,7 @@ void logger_log_part(struct part *p, unsigned int mask, size_t *offset,
 /**
  * @brief Dump a #gpart to the log.
  *
- * @param gpart The #gpart to dump.
+ * @param p The #gpart to dump.
  * @param mask The mask of the data to dump.
  * @param offset Pointer to the offset of the previous log of this particle.
  * @param dump The #dump in which to log the particle data.
@@ -196,7 +196,7 @@ void logger_log_gpart(struct gpart *p, unsigned int mask, size_t *offset,
   char *buff = dump_get(dump, size, &offset_new);
 
   /* Write the header. */
-  uint64_t temp = (((uint64_t)(offset_new - *offset)) & 0xffffffffffffffL) |
+  uint64_t temp = (((uint64_t)(offset_new - *offset)) & 0xffffffffffffffULL) |
                   ((uint64_t)mask << 56);
   memcpy(buff, &temp, 8);
   buff += 8;
@@ -248,7 +248,7 @@ void logger_log_timestamp(unsigned long long int timestamp, size_t *offset,
   char *buff = dump_get(dump, size, &offset_new);
 
   /* Write the header. */
-  uint64_t temp = (((uint64_t)(offset_new - *offset)) & 0xffffffffffffffL) |
+  uint64_t temp = (((uint64_t)(offset_new - *offset)) & 0xffffffffffffffULL) |
                   ((uint64_t)logger_mask_timestamp << 56);
   memcpy(buff, &temp, 8);
   buff += 8;
@@ -259,3 +259,184 @@ void logger_log_timestamp(unsigned long long int timestamp, size_t *offset,
   /* Update the log message offset. */
   *offset = offset_new;
 }
+
+/**
+ * @brief Read a logger message and store the data in a #part.
+ *
+ * @param p The #part in which to store the values.
+ * @param offset Pointer to the offset of the logger message in the buffer,
+ *        will be overwritten with the offset of the previous message.
+ * @param buff Pointer to the start of an encoded logger message.
+ *
+ * @return The mask containing the values read.
+ */
+
+int logger_read_part(struct part *p, size_t *offset, const char *buff) {
+
+  /* Jump to the offset. */
+  buff = &buff[*offset];
+
+  /* Start by reading the logger mask for this entry. */
+  uint64_t temp;
+  memcpy(&temp, buff, 8);
+  const int mask = temp >> 56;
+  *offset -= temp & 0xffffffffffffffULL;
+
+  /* We are only interested in particle data. */
+  if (mask & logger_mask_timestamp)
+    error("Trying to read timestamp as particle.");
+
+  /* Particle position as three doubles. */
+  if (mask & logger_mask_x) {
+    memcpy(p->x, buff, 3 * sizeof(double));
+    buff += 3 * sizeof(double);
+  }
+
+  /* Particle velocity as three floats. */
+  if (mask & logger_mask_v) {
+    memcpy(p->v, buff, 3 * sizeof(float));
+    buff += 3 * sizeof(float);
+  }
+
+  /* Particle accelleration as three floats. */
+  if (mask & logger_mask_a) {
+    memcpy(p->a_hydro, buff, 3 * sizeof(float));
+    buff += 3 * sizeof(float);
+  }
+
+  /* Particle internal energy as a single float. */
+  if (mask & logger_mask_u) {
+#if defined(GADGET2_SPH)
+    memcpy(&p->entropy, buff, sizeof(float));
+#else
+    memcpy(&p->u, buff, sizeof(float));
+#endif
+    buff += sizeof(float);
+  }
+
+  /* Particle smoothing length as a single float. */
+  if (mask & logger_mask_h) {
+    memcpy(&p->h, buff, sizeof(float));
+    buff += sizeof(float);
+  }
+
+  /* Particle density as a single float. */
+  if (mask & logger_mask_rho) {
+    memcpy(&p->rho, buff, sizeof(float));
+    buff += sizeof(float);
+  }
+
+  /* Particle constants, which is a bit more complicated. */
+  if (mask & logger_mask_rho) {
+    memcpy(&p->mass, buff, sizeof(float));
+    buff += sizeof(float);
+    memcpy(&p->id, buff, sizeof(long long));
+    buff += sizeof(long long);
+  }
+
+  /* Finally, return the mask of the values we just read. */
+  return mask;
+}
+
+/**
+ * @brief Read a logger message and store the data in a #gpart.
+ *
+ * @param p The #gpart in which to store the values.
+ * @param offset Pointer to the offset of the logger message in the buffer,
+ *        will be overwritten with the offset of the previous message.
+ * @param buff Pointer to the start of an encoded logger message.
+ *
+ * @return The mask containing the values read.
+ */
+
+int logger_read_gpart(struct gpart *p, size_t *offset, const char *buff) {
+
+  /* Jump to the offset. */
+  buff = &buff[*offset];
+
+  /* Start by reading the logger mask for this entry. */
+  uint64_t temp;
+  memcpy(&temp, buff, 8);
+  const int mask = temp >> 56;
+  *offset -= temp & 0xffffffffffffffULL;
+
+  /* We are only interested in particle data. */
+  if (mask & logger_mask_timestamp)
+    error("Trying to read timestamp as particle.");
+    
+  /* We can't store all part fields in a gpart. */
+  if (mask & (logger_mask_u | logger_mask_rho))
+    error("Trying to read SPH quantities into a gpart.");
+
+  /* Particle position as three doubles. */
+  if (mask & logger_mask_x) {
+    memcpy(p->x, buff, 3 * sizeof(double));
+    buff += 3 * sizeof(double);
+  }
+
+  /* Particle velocity as three floats. */
+  if (mask & logger_mask_v) {
+    memcpy(p->v_full, buff, 3 * sizeof(float));
+    buff += 3 * sizeof(float);
+  }
+
+  /* Particle accelleration as three floats. */
+  if (mask & logger_mask_a) {
+    memcpy(p->a_grav, buff, 3 * sizeof(float));
+    buff += 3 * sizeof(float);
+  }
+
+  /* Particle smoothing length as a single float. */
+  if (mask & logger_mask_h) {
+    memcpy(&p->epsilon, buff, sizeof(float));
+    buff += sizeof(float);
+  }
+
+  /* Particle constants, which is a bit more complicated. */
+  if (mask & logger_mask_rho) {
+    memcpy(&p->mass, buff, sizeof(float));
+    buff += sizeof(float);
+    memcpy(&p->id_or_neg_offset, buff, sizeof(long long));
+    buff += sizeof(long long);
+  }
+
+  /* Finally, return the mask of the values we just read. */
+  return mask;
+}
+
+/**
+ * @brief Read a logger message for a timestamp.
+ *
+ * @param t The timestamp in which to store the value.
+ * @param offset Pointer to the offset of the logger message in the buffer,
+ *        will be overwritten with the offset of the previous message.
+ * @param buff Pointer to the start of an encoded logger message.
+ *
+ * @return The mask containing the values read.
+ */
+
+int logger_read_timestamp(unsigned long long int *t, size_t *offset, const char *buff) {
+
+  /* Jump to the offset. */
+  buff = &buff[*offset];
+
+  /* Start by reading the logger mask for this entry. */
+  uint64_t temp;
+  memcpy(&temp, buff, 8);
+  const int mask = temp >> 56;
+  *offset -= temp & 0xffffffffffffffULL;
+
+  /* We are only interested in timestamps. */
+  if (!(mask & logger_mask_timestamp))
+    error("Trying to read timestamp from a particle.");
+    
+  /* Make sure we don't have extra fields. */
+  if (mask != logger_mask_timestamp)
+    error("Timestamp message contains extra fields.");
+
+  /* Copy the timestamp value from the buffer. */
+  memcpy(t, buff, sizeof(unsigned long long int));
+
+  /* Finally, return the mask of the values we just read. */
+  return mask;
+}
diff --git a/src/logger.h b/src/logger.h
index add20e8bf71b7e07359a4c666eeaee7f54dd1cbf..32fae752c2ae13a143809d9df3030dbc06b0942d 100644
--- a/src/logger.h
+++ b/src/logger.h
@@ -77,7 +77,11 @@ void logger_log_part(struct part *p, unsigned int mask, size_t *offset,
                      struct dump *dump);
 void logger_log_gpart(struct gpart *p, unsigned int mask, size_t *offset,
                       struct dump *dump);
-void logger_log_timestamp(unsigned long long int timestamp, size_t *offset,
+void logger_log_timestamp(unsigned long long int t, size_t *offset,
                           struct dump *dump);
+int logger_read_part(struct part *p, size_t *offset, const char *buff);
+int logger_read_gpart(struct gpart *p, size_t *offset, const char *buff);
+int logger_read_timestamp(unsigned long long int *t, size_t *offset,
+                          const char *buff);
 
 #endif /* SWIFT_LOGGER_H */