/// <summary> /// Decodes a <see cref="ByteBuffer"/> into an archive. /// </summary> /// <param name="buffer">The buffer to decode</param> /// <param name="size">The size of the archive</param> /// <returns>An <see cref="Archive"/> with the decoded byte buffer</returns> public static Archive DecodeArchive(ByteBuffer buffer, int size) { var archive = new Archive(size); /* read the number of chunks at the end of the archive */ buffer.position(buffer.limit() - 1); var chunks = buffer.get() & 0xFF; var chunkSizes = ArrayUtility.AsRectangularArray <int>(chunks, size); var sizes = new int[size]; buffer.position(buffer.limit() - 1 - chunks * size * 4); for (var chunk = 0; chunk < chunks; chunk++) { var chunkSize = 0; for (var id = 0; id < size; id++) { /* read the delta-encoded chunk length */ var delta = buffer.getInt(); chunkSize += delta; chunkSizes[chunk][id] = chunkSize; // store the size of this chunk sizes[id] += chunkSize; // and add it to the size of the whole file } } /* allocate the buffers for the child entries */ for (var id = 0; id < size; id++) { archive.Entries[id] = ByteBuffer.allocate(sizes[id]); } /* read the data into the buffers */ buffer.position(0); for (var chunk = 0; chunk < chunks; chunk++) { for (var id = 0; id < size; id++) { var chunkSize = chunkSizes[chunk][id]; var temp = new byte[chunkSize]; buffer.get(temp); archive.Entries[id].put(temp); } } /* flip all of the buffers */ for (var id = 0; id < size; id++) { archive.Entries[id].flip(); } return(archive); }