From 91930d915c2e4cd9ba517324829cb4f82c4d3d3c Mon Sep 17 00:00:00 2001 From: niamtokik Date: Tue, 30 Mar 2021 11:48:59 +0000 Subject: [PATCH] add license, update readme and start to work on encoding functions --- LICENSE | 14 ++++++++++ README.md | 21 +++++++++++++++ lib/dotzip.ex | 11 +++++++- lib/dotzip/central_directory_header.ex | 36 ++++++++++++++++++++++++-- 4 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d9f6448 --- /dev/null +++ b/LICENSE @@ -0,0 +1,14 @@ +Copyright (c) 2021 Mathieu Kerjouan + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index d4354b2..6d5f774 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,18 @@ # Dotzip +> ZIP is one of the most widely used compressed file formats. It is +> universally used to aggregate, compress, and encrypt files into a +> single interoperable container. No specific use or application need +> is defined by this format and no specific implementation guidance is +> provided. This document provides details on the storage format for +> creating ZIP files. Information is provided on the records and +> fields that describe what a ZIP file is. -- from [official +> specification +> file](https://pkware.cachefly.net/webdocs/APPNOTE/APPNOTE-6.3.3.TXT) + +Note: This project is a work in progress. Please don't use it in +production. + ## Installation If [available in Hex](https://hex.pm/docs/publish), the package can be installed @@ -36,6 +49,14 @@ Dotzip.decode(file) * https://pkware.cachefly.net/webdocs/APPNOTE/APPNOTE-6.3.3.TXT * https://en.wikipedia.org/wiki/ZIP_(file_format) +## Trademarks + +> PKWARE, PKZIP, SecureZIP, and PKSFX are registered trademarks of +> PKWARE, Inc. in the United States and elsewhere. PKPatchMaker, +> Deflate64, and ZIP64 are trademarks of PKWARE, Inc. Other marks +> referenced within this document appear for identification purposes +> only and are the property of their respective owners. + ## Notes Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc) diff --git a/lib/dotzip.ex b/lib/dotzip.ex index 34405be..412c6ce 100644 --- a/lib/dotzip.ex +++ b/lib/dotzip.ex @@ -11,10 +11,19 @@ defmodule Dotzip do {local, central, e, rr} end - def read(file) do + def decode_file(file) do {:ok, data} = :file.read_file(file) decode(data) end + + + def encode(_data) do + {:error, :not_supported} + end + + def encode_file(_file) do + {:error, :not_supported} + end end diff --git a/lib/dotzip/central_directory_header.ex b/lib/dotzip/central_directory_header.ex index 49b2faf..00c227c 100644 --- a/lib/dotzip/central_directory_header.ex +++ b/lib/dotzip/central_directory_header.ex @@ -1,25 +1,49 @@ defmodule Dotzip.CentralDirectoryHeader do + defp signature() do + << 0x50, 0x4b, 0x01, 0x02 >> + end + defp signature(<< 0x50, 0x4b, 0x01, 0x02, rest::bitstring >>) do {:ok, %{}, rest} end + defp encode_signature(data) when is_map(data) do + {:ok, data, signature()} + end + defp version_made({:ok, data, << version::binary-size(2), rest::bitstring >>}) do {:ok, Map.put(data, :version_made, version), rest} end + defp encode_version_made({:ok, %{ :version_made => version_made } = data, buffer}) do + {:ok, data, << buffer::bitstring, version_made::binary-size(2) >>} + end + defp version_needed({:ok, data, << version::binary-size(2), rest::bitstring >>}) do {:ok, Map.put(data, :version_needed, version), rest} end + + defp encode_version_needed({:ok, %{ :version_needed => version_needed } = data, buffer}) do + {:ok, data, << buffer::bitstring, version_needed::binary-size(2) >>} + end defp purpose_flag({:ok, data, << purpose_flag::binary-size(2), rest::bitstring >>}) do {:ok, Map.put(data, :purpose_flag, purpose_flag), rest} end + defp encode_purpose_flag({:ok, %{ :purpose_flag => purpose_flag } = data, buffer}) do + {:ok, data, << buffer::bitstring, purpose_flag::binary-size(2) >>} + end + defp compression_method({:ok, data, << compression_method::binary-size(2), rest::bitstring >>}) do {:ok, Map.put(data, :compression_method, compression_method), rest} end + defp encode_compression_method({:ok, %{ :compression_method => compression_method } = data, buffer}) do + {:ok, data, << buffer::bitstring, compression_method::binary-size(2) >>} + end + defp last_modification_time({:ok, data, << last_modification::little-size(16), rest::bitstring >>}) do {:ok, Map.put(data, :last_modification_time, last_modification), rest} end @@ -86,8 +110,8 @@ defmodule Dotzip.CentralDirectoryHeader do {:ok, Map.put(data, :file_comment, file_comment), r} end - def decode(file) do - {:ok, central_directory_header, rest} = signature(file) + def decode(data) when is_bitstring(data) do + {:ok, central_directory_header, rest} = signature(data) |> version_made() |> version_needed() |> purpose_flag() @@ -108,5 +132,13 @@ defmodule Dotzip.CentralDirectoryHeader do |> extra_field() |> file_comment() end + + def encode(data) when is_map(data) do + encode_signature(data) + |> encode_version_made() + |> encode_version_needed() + |> encode_purpose_flag() + |> encode_compression_method() + end end