Skip to content

Commit

Permalink
Refactor base64 and additional testcase for without padding
Browse files Browse the repository at this point in the history
  • Loading branch information
Joe-Abraham committed Nov 21, 2023
1 parent b58e4b6 commit 3834919
Show file tree
Hide file tree
Showing 7 changed files with 250 additions and 167 deletions.
50 changes: 50 additions & 0 deletions velox/common/encode/Base.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "velox/common/encode/Base.h"

#include <stdint.h>

namespace facebook::velox::encoding {

bool Base::isPadded(const char* data, size_t len) {
return (len > 0 && data[len - 1] == kBasePad) ? true : false;
}

size_t Base::countPadding(const char* src, size_t len) {
size_t padding_count = 0;
while (len > 0 && src[len - 1] == kBasePad) {
padding_count++;
len--;
}

return padding_count;
}

uint8_t Base::baseReverseLookup(
const int base,
char p,
const Base::ReverseIndex& reverse_lookup) {
auto curr = reverse_lookup[(uint8_t)p];
// Value of encoded character shall be less than base.
if (curr >= base) {
throw BaseException(
"Base::decode() - invalid input string: invalid characters");
}

return curr;
}

} // namespace facebook::velox::encoding
92 changes: 92 additions & 0 deletions velox/common/encode/Base.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once

#include <exception>
#include <map>
#include <string>

#include <folly/Range.h>

namespace facebook::velox::encoding {

class BaseException : public std::exception {
public:
explicit BaseException(const char* msg) : msg_(msg) {}
const char* what() const noexcept override {
return msg_;
}

protected:
const char* msg_;
};

/// Base class for all binary encoding scheme for reversibly translating between
/// byte sequences and printable ASCII strings specified by RFC 4648.
class Base {
public:
using Charset = std::array<char, 64>;
using ReverseIndex = std::array<uint8_t, 256>;

// Checks is there padding in encoded data
static bool isPadded(const char* src, size_t len);

// Counts the number of padding characters in encoded data.
static size_t countPadding(const char* src, size_t len);

// Gets value corresponding to an encoded character
static uint8_t
baseReverseLookup(const int base, char p, const ReverseIndex& table);

// Padding character used in encoding
constexpr static char kBasePad = '=';
};

// Validate the character in charset with ReverseIndex table
constexpr bool checkForwardIndex(
uint8_t idx,
const Base::Charset& charset,
const Base::ReverseIndex& table) {
return (table[static_cast<uint8_t>(charset[idx])] == idx) &&
(idx > 0 ? checkForwardIndex(idx - 1, charset, table) : true);
}

/// Similar to strchr(), but for null-terminated const strings.
/// Another difference is that we do not consider "\0" to be present in the
/// string.
/// Returns true if "str" contains the character c.
constexpr bool constCharsetContains(
const Base::Charset& charset,
int base,
uint8_t idx,
const char c) {
return idx < base &&
((charset[idx] == c) || constCharsetContains(charset, base, idx + 1, c));
}

// Validate the value in ReverseIndex table with charset.
constexpr bool checkReverseIndex(
uint8_t idx,
const Base::Charset& charset,
int base,
const Base::ReverseIndex& table) {
return (table[idx] == 255
? !constCharsetContains(charset, base, 0, static_cast<char>(idx))
: (charset[table[idx]] == idx)) &&
(idx > 0 ? checkReverseIndex(idx - 1, charset, base, table) : true);
}

} // namespace facebook::velox::encoding
Loading

0 comments on commit 3834919

Please sign in to comment.