Skip to content

Commit

Permalink
S2
Browse files Browse the repository at this point in the history
  • Loading branch information
maxirmx committed Dec 14, 2024
1 parent 509180e commit e7164b0
Show file tree
Hide file tree
Showing 3 changed files with 607 additions and 0 deletions.
101 changes: 101 additions & 0 deletions include/tebako-package-descriptor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/**
*
* Copyright (c) 2024 [Ribose Inc](https://www.ribose.com).
* All rights reserved.
* This file is a part of tebako
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/

#pragma once

#include <optional>
#include <string>
#include <cstring>
#include <stdexcept>
#include <sstream>
#include <vector>

namespace tebako {

class package_descriptor {
private:
uint16_t ruby_version_major;
uint16_t ruby_version_minor;
uint16_t ruby_version_patch;
uint16_t tebako_version_major;
uint16_t tebako_version_minor;
uint16_t tebako_version_patch;
std::string mount_point;
std::string entry_point;
std::optional<std::string> cwd;

bool little_endian;

public:
// Deleted default constructor
package_descriptor() = delete;

// Constructor for deserialization
explicit package_descriptor(const std::vector<uint8_t>& buffer);
// Constructor from version strings and other parameters
package_descriptor(const std::string& ruby_version, const std::string& tebako_version,
const std::string& mount_point, const std::string& entry_point, const std::optional<std::string>& cwd);
// Serialize the object to a binary format
std::vector<uint8_t> serialize() const;

uint16_t get_ruby_version_major() const { return ruby_version_major; }
uint16_t get_ruby_version_minor() const { return ruby_version_minor; }
uint16_t get_ruby_version_patch() const { return ruby_version_patch; }
uint16_t get_tebako_version_major() const { return tebako_version_major; }
uint16_t get_tebako_version_minor() const { return tebako_version_minor; }
uint16_t get_tebako_version_patch() const { return tebako_version_patch; }
const std::string& get_mount_point() const { return mount_point; }
const std::string& get_entry_point() const { return entry_point; }
const std::optional<std::string>& get_cwd() const { return cwd; }

static bool is_little_endian() {
uint16_t number = 1;
return *(reinterpret_cast<uint8_t*>(&number)) == 1;
}

// Convert a 16-bit value to little-endian byte order
uint16_t to_little_endian(uint16_t value) {
if (little_endian) {
return value;
} else {
return (value >> 8) | (value << 8);
}
}

// Convert a 16-bit value from little-endian byte order
uint16_t from_little_endian(uint16_t value) {
if (little_endian) {
return value;
} else {
return (value >> 8) | (value << 8);
}
}
};

} // namespace tebako
145 changes: 145 additions & 0 deletions src/tebako-package-descriptor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/**
*
* Copyright (c) 2024 [Ribose Inc](https://www.ribose.com).
* All rights reserved.
* This file is a part of tebako
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/

#include "tebako-pch-pp.h"
#include "tebako-package-descriptor.h"

namespace tebako {

// Constructor for deserialization
package_descriptor::package_descriptor(const std::vector<uint8_t>& buffer):
little_endian(is_little_endian()) {
size_t offset = 0;

auto read_from_buffer = [&buffer, &offset](void* data, size_t size) {
if (offset + size > buffer.size()) {
throw std::out_of_range("Buffer too short for deserialization");
}
std::memcpy(data, buffer.data() + offset, size);
offset += size;
};

// Read fixed-size fields
read_from_buffer(&ruby_version_major, sizeof(ruby_version_major));
read_from_buffer(&ruby_version_minor, sizeof(ruby_version_minor));
read_from_buffer(&ruby_version_patch, sizeof(ruby_version_patch));
read_from_buffer(&tebako_version_major, sizeof(tebako_version_major));
read_from_buffer(&tebako_version_minor, sizeof(tebako_version_minor));
read_from_buffer(&tebako_version_patch, sizeof(tebako_version_patch));

// Read mount_point size and content
uint16_t mount_point_size;
read_from_buffer(&mount_point_size, sizeof(mount_point_size));
if (offset + mount_point_size > buffer.size()) {
throw std::out_of_range("Buffer too short for mount_point");
}
mount_point.resize(mount_point_size);
read_from_buffer(mount_point.data(), mount_point_size);

// Read entry_point size and content
uint16_t entry_point_size;
read_from_buffer(&entry_point_size, sizeof(entry_point_size));
if (offset + entry_point_size > buffer.size()) {
throw std::out_of_range("Buffer too short for entry_point");
}
entry_point.resize(entry_point_size);
read_from_buffer(entry_point.data(), entry_point_size);

// Read cwd presence flag and content if present
uint8_t cwd_present;
read_from_buffer(&cwd_present, sizeof(cwd_present));
if (cwd_present) {
uint16_t cwd_size;
read_from_buffer(&cwd_size, sizeof(cwd_size));
if (offset + cwd_size > buffer.size()) {
throw std::out_of_range("Buffer too short for cwd");
}
std::string cwd_value(cwd_size, '\0');
read_from_buffer(cwd_value.data(), cwd_size);
cwd = cwd_value;
} else {
cwd.reset();
}
}

// Constructor from version strings and other parameters
package_descriptor::package_descriptor(const std::string& ruby_version, const std::string& tebako_version, const std::string& mount_point, const std::string& entry_point, const std::optional<std::string>& cwd)
: mount_point(mount_point), entry_point(entry_point), cwd(cwd), little_endian(is_little_endian()) {
auto parse_version = [](const std::string& version, uint16_t& major, uint16_t& minor, uint16_t& patch) {
std::stringstream ss(version);
char dot;
if (!(ss >> major >> dot >> minor >> dot >> patch) || dot != '.') {
throw std::invalid_argument("Invalid version format: " + version);
}
};

parse_version(ruby_version, ruby_version_major, ruby_version_minor, ruby_version_patch);
parse_version(tebako_version, tebako_version_major, tebako_version_minor, tebako_version_patch);
}

// Serialize the object to a binary format
std::vector<uint8_t> package_descriptor::serialize() const {
std::vector<uint8_t> buffer;
auto append_to_buffer = [&buffer](const void* data, size_t size) {
const uint8_t* bytes = static_cast<const uint8_t*>(data);
buffer.insert(buffer.end(), bytes, bytes + size);
};

// Append fixed-size fields
append_to_buffer(&ruby_version_major, sizeof(ruby_version_major));
append_to_buffer(&ruby_version_minor, sizeof(ruby_version_minor));
append_to_buffer(&ruby_version_patch, sizeof(ruby_version_patch));
append_to_buffer(&tebako_version_major, sizeof(tebako_version_major));
append_to_buffer(&tebako_version_minor, sizeof(tebako_version_minor));
append_to_buffer(&tebako_version_patch, sizeof(tebako_version_patch));

// Append mount_point size and content
uint16_t mount_point_size = static_cast<uint16_t>(mount_point.size());
append_to_buffer(&mount_point_size, sizeof(mount_point_size));
append_to_buffer(mount_point.data(), mount_point_size);

// Append entry_point size and content
uint16_t entry_point_size = static_cast<uint16_t>(entry_point.size());
append_to_buffer(&entry_point_size, sizeof(entry_point_size));
append_to_buffer(entry_point.data(), entry_point_size);

// Append cwd presence flag and content if present
uint8_t cwd_present = cwd.has_value() ? 1 : 0;
append_to_buffer(&cwd_present, sizeof(cwd_present));
if (cwd) {
uint16_t cwd_size = static_cast<uint16_t>(cwd->size());
append_to_buffer(&cwd_size, sizeof(cwd_size));
append_to_buffer(cwd->data(), cwd_size);
}

return buffer;
}


} // namespace tebako
Loading

0 comments on commit e7164b0

Please sign in to comment.