Commit dd6f3bcb authored by roshii's avatar roshii

Getting started

parents
Pipeline #68357980 canceled with stages
docs/build/
# This file is a template, and might need editing before it works on your project.
# This is an example .gitlab-ci.yml file to test (and optionally report the coverage
# results of) your [Julia][1] packages. Please refer to the [documentation][2]
# for more information about package development in Julia.
#
# Here, it is assumed that your Julia package is named `MyPackage`. Change it to
# whatever name you have given to your package.
#
# [1]: http://julialang.org/
# [2]: https://docs.julialang.org/en/v1/manual/documentation/index.html
# Below is the template to run your tests in Julia
.test_template: &test_definition
# Uncomment below if you would like to run the tests on specific references
# only, such as the branches `master`, `development`, etc.
# only:
# - master
# - development
script:
# Let's run the tests. Substitute `coverage = false` below, if you do not
# want coverage results.
- julia -e 'using Pkg; Pkg.clone(pwd()); Pkg.build("BitConverter"); Pkg.test("BitConverter"; coverage = true)'
# Comment out below if you do not want coverage results.
- julia -e 'using Pkg; Pkg.add("Coverage");
import BitConverter; cd(joinpath(dirname(pathof(BitConverter)), ".."));
using Coverage; cl, tl = get_summary(process_folder());
println("(", cl/tl*100, "%) covered")'
# Name a test and select an appropriate image.
# images comes from Docker hub
# test:0.7:
# image: julia:0.7
# <<: *test_definition
test:1.0:
image: julia:1.0
<<: *test_definition
# Maybe you would like to test your package against the development branch:
# test:1.1-dev (not sure there is such an image in docker, so not tested yet):
# image: julia:v1.1-dev
# # ... allowing for failures, since we are testing against the development
# # branch:
# allow_failure: true
# <<: *test_definition
# REMARK: Do not forget to enable the coverage feature for your project, if you
# are using code coverage reporting above. This can be done by
#
# - Navigating to the `CI/CD Pipelines` settings of your project,
# - Copying and pasting the default `Simplecov` regex example provided, i.e.,
# `\(\d+.\d+\%\) covered` in the `test coverage parsing` textfield.
# Example documentation deployment
pages:
image: julia:1.0
stage: deploy
script:
- apt-get update -qq && apt-get install -y git # needed by Documenter
- julia -e 'using Pkg; Pkg.clone(pwd()); Pkg.build("BitConverter");' # rebuild Julia (can be put somewhere else I'm sure
- julia -e 'using Pkg; import BitConverter; Pkg.add("Documenter")' # install Documenter
- julia --color=yes docs/make.jl # make documentation
- mv docs/build public # move to the directory picked up by Gitlab pages
artifacts:
paths:
- public
only:
- master
# WARNING: This template is using the `julia` images from [Docker
# Hub][3]. One can use custom Julia images and/or the official ones found
# in the same place. However, care must be taken to correctly locate the binary
# file (`/opt/julia/bin/julia` above), which is usually given on the image's
# description page.
#
# [3]: https://hub.docker.com/_/julia/
MIT License
Copyright (c) 2019 Simon Castano
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
name = "BitConverter"
uuid = "3a3ce9e8-98e7-11e9-0fa0-055639f146d3"
license = "MIT"
authors = ["Simon Castano <simon@brane.cc>"]
version = "0.1.0"
[extras]
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
[targets]
test = ["Test"]
using Documenter, BitConverter
makedocs(sitename="BitConverter",
doctest=true)
# BitConverter.jl
Converts base data types to an array of bytes, and an array of bytes to base
data types.
So far Integer only are implemented.
## Functions
```@docs
bytes(x::Integer; len::Integer, little_endian::Bool)
big(x::Vector{UInt8})
Int(x::Vector{UInt8}; little_endian::Bool)
```
## Examples
```julia
julia> bytes(big(2)^32)
5-element Array{UInt8,1}:
0x01
0x00
0x00
0x00
0x00
```
```julia
julia> x = rand(UInt8, 8)
8-element Array{UInt8,1}:
0xd3
0x82
0x42
0xa7
0xd8
0x2b
0xd0
0xc5
julia> big(x)
15240817377628901573
julia> Int(rand(UInt8, 2))
48868
julia> Int(rand(UInt8, 8))
-3411029373876830527
```
## Buy me a cup of coffee
[Donate Bitcoin](bitcoin:1786ytdyKz1TJgpVM34DKDB85eEQkvwgjo)
## Index
```@index
```
module BitConverter
export bytes, big, Int
"""
bytes(x::Integer; len::Integer, little_endian::Bool)
-> Vector{len, UInt8}
Convert an Integer `x` to a Vector{UInt8}
"""
function bytes(x::Integer; len::Integer=0, little_endian::Bool=false)
result = reinterpret(UInt8, [hton(x)])
i = findfirst(x -> x != 0x00, result)
if len != 0
i = length(result) - len + 1
end
result = result[i:end]
if little_endian
reverse!(result)
end
return result
end
function bytes(x::BigInt)
n_bytes_with_zeros = x.size * sizeof(Sys.WORD_SIZE)
uint8_ptr = convert(Ptr{UInt8}, x.d)
n_bytes_without_zeros = 1
if ENDIAN_BOM == 0x04030201
# the minimum should be 1, else the result array will be of
# length 0
for i in n_bytes_with_zeros:-1:1
if unsafe_load(uint8_ptr, i) != 0x00
n_bytes_without_zeros = i
break
end
end
result = Array{UInt8}(undef, n_bytes_without_zeros)
for i in 1:n_bytes_without_zeros
@inbounds result[n_bytes_without_zeros + 1 - i] = unsafe_load(uint8_ptr, i)
end
else
for i in 1:n_bytes_with_zeros
if unsafe_load(uint8_ptr, i) != 0x00
n_bytes_without_zeros = i
break
end
end
result = Array{UInt8}(undef, n_bytes_without_zeros)
for i in 1:n_bytes_without_zeros
@inbounds result[i] = unsafe_load(uint8_ptr, i)
end
end
return result
end
"""
Int(x::Vector{UInt8}; little_endian::Bool)
-> Integer
Convert a Vector{UInt8} to an Integer
"""
function Core.Int(x::Vector{UInt8}; little_endian::Bool=false)
if length(x) > 8
big(x)
else
missing_zeros = div(Sys.WORD_SIZE, 8) - length(x)
if missing_zeros > 0
if little_endian
for i in 1:missing_zeros
push!(x,0x00)
end
else
for i in 1:missing_zeros
pushfirst!(x,0x00)
end
end
end
if ENDIAN_BOM == 0x04030201 && little_endian
elseif ENDIAN_BOM == 0x04030201 || little_endian
reverse!(x)
end
return reinterpret(Int, x)[1]
end
end
"""
Base.big(x::Vector{UInt8}) -> BigInt
Convert a Vector{UInt8} to a BigInt
"""
function Base.big(x::Vector{UInt8})
hex = bytes2hex(x)
return parse(BigInt, hex, base=16)
end
end # module
# Alternative implementation
function Base.Int(x::Vector{UInt8})
if isempty(x)
return 0
end
if length(x) > div(Sys.WORD_SIZE, 8)
T = BigInt
else
T = Int
end
result = zero(T)
if ENDIAN_BOM == 0x01020304
reverse!(x)
end
for c in x
result <<= 8
result += c
end
return result
end
function faster_big(x::Vector{UInt8})
xsize = cld(length(x), Base.GMP.BITS_PER_LIMB / 8)
if ENDIAN_BOM == 0x04030201
reverse!(x)
end
result = Base.GMP.MPZ.realloc2(xsize * Base.GMP.BITS_PER_LIMB)
result.size = xsize
unsafe_copyto!(result.d, convert(Ptr{Base.GMP.Limb}, pointer(x)), xsize)
return result
end
# Copyright (c) 2019 Guido Kraemer
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
using BitConverter, Test
files = readdir(".")
# use only files that are named test_*.jl and start with the newest
filter!(x -> occursin(r"^test_.*\.jl$", x), files)
sort!(files, by = x -> stat(x).mtime, rev = true)
for f in files
include(f)
end
@testset "Integer Convertions" begin
tests = ((11, [0x0b]),
(18145,[0x46, 0xe1]),
(big(18)^256, [0x0b, 0x51, 0xea, 0xa7, 0x75, 0x9a, 0x45, 0x93, 0x57, 0xc0, 0x6f, 0x65, 0x48, 0x7c, 0xe1, 0x8f, 0x23, 0xcf, 0x2b, 0x52, 0xbb, 0xab, 0x34, 0x98, 0x3e, 0x22, 0xb2, 0xa5, 0xca, 0xdd, 0xe3, 0x3f, 0xcb, 0x0f, 0x1a, 0x5a, 0xbf, 0xca, 0x90, 0xc4, 0xf8, 0x13, 0x28, 0x05, 0x2d, 0x31, 0x1f, 0xe7, 0x77, 0x93, 0x41, 0x7d, 0xd7, 0x70, 0x5c, 0x83, 0x09, 0x8e, 0xc0, 0xc7, 0x32, 0xe0, 0xf9, 0xc8, 0x7f, 0xe3, 0xaa, 0x65, 0xac,0x28, 0x94, 0x83, 0x76, 0x0f, 0xbd, 0x2a, 0x7e, 0x53, 0x35, 0xbd, 0x07, 0x5f, 0x4d, 0x13, 0xeb, 0xbd, 0x76, 0x79, 0xef, 0x1b, 0x43, 0x06, 0x89, 0x0c, 0x1d, 0x66, 0x0d, 0x12, 0x76, 0xf1, 0xe8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]))
@testset "bytes()" begin
for t in tests
@test bytes(t[1]) == t[2]
end
end
@testset "Int()" begin
for t in tests
@test Int(t[2]) == t[1]
end
end
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment