Compare commits
10 commits
1936134aad
...
95026b5d1e
Author | SHA1 | Date | |
---|---|---|---|
|
95026b5d1e | ||
|
63e06fdf51 | ||
|
c5f25eec89 | ||
|
8c7931ea02 | ||
|
1ee736809a | ||
|
6d305686f2 | ||
|
7a95f93924 | ||
|
8a1240e802 | ||
|
2faf9ceb2c | ||
|
90e935af6e |
9 changed files with 680 additions and 8 deletions
5
LICENSE
5
LICENSE
|
@ -1,6 +1,9 @@
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2016 BitShares Munich IVS
|
Copyright (c) 2019 AGORISE, LTD.
|
||||||
|
An International Business Company, Cyprus Reg# ΗΕ375959
|
||||||
|
|
||||||
|
Contains works from BitShares Munich IVS
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
|
@ -1,2 +1,9 @@
|
||||||
# c-ipld
|
# c-ipld
|
||||||
Implementation of the IPLD spec in C.
|
Implementation of the IPLD spec in C.
|
||||||
|
|
||||||
|
### A very simple tutorial is available in ipld_tut.c
|
||||||
|
### The header has every function documented.
|
||||||
|
## Uncertain To Do:
|
||||||
|
------
|
||||||
|
#### * Formatting links as such: foo/bar : {}
|
||||||
|
#### * Deep searching nodes
|
||||||
|
|
201
base58.c
Normal file
201
base58.c
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2014 Luke Dashjr
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the standard MIT license. See COPYING for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
static const char b58digits_ordered[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
||||||
|
|
||||||
|
static const int8_t b58digits_map[] = {
|
||||||
|
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
|
||||||
|
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
|
||||||
|
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
|
||||||
|
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8,-1,-1,-1,-1,-1,-1,
|
||||||
|
-1, 9,10,11,12,13,14,15, 16,-1,17,18,19,20,21,-1,
|
||||||
|
22,23,24,25,26,27,28,29, 30,31,32,-1,-1,-1,-1,-1,
|
||||||
|
-1,33,34,35,36,37,38,39, 40,41,42,43,-1,44,45,46,
|
||||||
|
47,48,49,50,51,52,53,54, 55,56,57,-1,-1,-1,-1,-1,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* convert a base58 encoded string into a binary array
|
||||||
|
* @param b58 the base58 encoded string
|
||||||
|
* @param base58_size the size of the encoded string
|
||||||
|
* @param bin the results buffer
|
||||||
|
* @param binszp the size of the results buffer
|
||||||
|
* @returns true(1) on success
|
||||||
|
*/
|
||||||
|
int libp2p_crypto_encoding_base58_decode(const char* b58, size_t base58_size, unsigned char** bin, size_t* binszp)
|
||||||
|
{
|
||||||
|
size_t binsz = *binszp;
|
||||||
|
const unsigned char* b58u = (const void*)b58;
|
||||||
|
unsigned char* binu = *bin;
|
||||||
|
size_t outisz = (binsz + 3) / 4;
|
||||||
|
uint32_t outi[outisz];
|
||||||
|
uint64_t t;
|
||||||
|
uint32_t c;
|
||||||
|
size_t i, j;
|
||||||
|
uint8_t bytesleft = binsz % 4;
|
||||||
|
uint32_t zeromask = bytesleft ? (0xffffffff << (bytesleft * 8)) : 0;
|
||||||
|
unsigned zerocount = 0;
|
||||||
|
size_t b58sz;
|
||||||
|
|
||||||
|
b58sz = strlen(b58);
|
||||||
|
|
||||||
|
memset(outi, 0, outisz * sizeof(*outi));
|
||||||
|
|
||||||
|
// Leading zeros, just count
|
||||||
|
for (i = 0; i < b58sz && !b58digits_map[b58u[i]]; ++i) {
|
||||||
|
++zerocount;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; i < b58sz; ++i) {
|
||||||
|
if (b58u[i] & 0x80) {
|
||||||
|
// High-bit set on invalid digit
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (b58digits_map[b58u[i]] == -1) {
|
||||||
|
// Invalid base58 digit
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
c = (unsigned)b58digits_map[b58u[i]];
|
||||||
|
for (j = outisz; j--;) {
|
||||||
|
t = ((uint64_t)outi[j]) * 58 + c;
|
||||||
|
c = (t & 0x3f00000000) >> 32;
|
||||||
|
outi[j] = t & 0xffffffff;
|
||||||
|
}
|
||||||
|
if (c) {
|
||||||
|
// Output number too big (carry to the next int32)
|
||||||
|
memset(outi, 0, outisz * sizeof(*outi));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (outi[0] & zeromask) {
|
||||||
|
// Output number too big (last int32 filled too far)
|
||||||
|
memset(outi, 0, outisz * sizeof(*outi));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
j = 0;
|
||||||
|
switch (bytesleft) {
|
||||||
|
case 3:
|
||||||
|
*(binu++) = (outi[0] & 0xff0000) >> 16;
|
||||||
|
case 2:
|
||||||
|
*(binu++) = (outi[0] & 0xff00) >> 8;
|
||||||
|
case 1:
|
||||||
|
*(binu++) = (outi[0] & 0xff);
|
||||||
|
++j;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; j < outisz; ++j) {
|
||||||
|
*(binu++) = (outi[j] >> 0x18) & 0xff;
|
||||||
|
*(binu++) = (outi[j] >> 0x10) & 0xff;
|
||||||
|
*(binu++) = (outi[j] >> 8) & 0xff;
|
||||||
|
*(binu++) = (outi[j] >> 0) & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count canonical base58 byte count
|
||||||
|
binu = *bin;
|
||||||
|
for (i = 0; i < binsz; ++i) {
|
||||||
|
if (binu[i]) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
--*binszp;
|
||||||
|
}
|
||||||
|
*binszp += zerocount;
|
||||||
|
|
||||||
|
memset(outi, 0, outisz * sizeof(*outi));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* encode an array of bytes into a base58 string
|
||||||
|
* @param binary_data the data to be encoded
|
||||||
|
* @param binary_data_size the size of the data to be encoded
|
||||||
|
* @param base58 the results buffer
|
||||||
|
* @param base58_size the size of the results buffer
|
||||||
|
* @returns true(1) on success
|
||||||
|
*/
|
||||||
|
//int libp2p_crypto_encoding_base58_encode(const unsigned char* binary_data, size_t binary_data_size, unsigned char* base58, size_t* base58_size)
|
||||||
|
int libp2p_crypto_encoding_base58_encode(const unsigned char* data, size_t binsz, unsigned char** b58, size_t* b58sz)
|
||||||
|
{
|
||||||
|
const uint8_t* bin = data;
|
||||||
|
int carry;
|
||||||
|
ssize_t i, j, high, zcount = 0;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
while (zcount < (ssize_t)binsz && !bin[zcount]) {
|
||||||
|
++zcount;
|
||||||
|
}
|
||||||
|
|
||||||
|
size = (binsz - zcount) * 138 / 100 + 1;
|
||||||
|
uint8_t buf[size];
|
||||||
|
memset(buf, 0, size);
|
||||||
|
|
||||||
|
for (i = zcount, high = size - 1; i < (ssize_t)binsz; ++i, high = j) {
|
||||||
|
for (carry = bin[i], j = size - 1; (j > high) || carry; --j) {
|
||||||
|
carry += 256 * buf[j];
|
||||||
|
buf[j] = carry % 58;
|
||||||
|
carry /= 58;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < (ssize_t)size && !buf[j]; ++j)
|
||||||
|
;
|
||||||
|
|
||||||
|
if (*b58sz <= zcount + size - j) {
|
||||||
|
*b58sz = zcount + size - j + 1;
|
||||||
|
memset(buf, 0, size);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zcount) {
|
||||||
|
memset(b58, '1', zcount);
|
||||||
|
}
|
||||||
|
for (i = zcount; j < (ssize_t)size; ++i, ++j) {
|
||||||
|
(*b58)[i] = b58digits_ordered[buf[j]];
|
||||||
|
}
|
||||||
|
(*b58)[i] = '\0';
|
||||||
|
*b58sz = i + 1;
|
||||||
|
|
||||||
|
memset(buf, 0, size);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* calculate the size of the binary results based on an incoming base58 string
|
||||||
|
* @param base58_string the string
|
||||||
|
* @returns the size in bytes had the string been decoded
|
||||||
|
*/
|
||||||
|
size_t libp2p_crypto_encoding_base58_decode_size(const unsigned char* base58_string) {
|
||||||
|
size_t string_length = strlen((char*)base58_string);
|
||||||
|
size_t decoded_length = 0;
|
||||||
|
size_t radix = strlen(b58digits_ordered);
|
||||||
|
double bits_per_digit = log2(radix);
|
||||||
|
|
||||||
|
decoded_length = floor(string_length * bits_per_digit / 8);
|
||||||
|
return decoded_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* calculate the max length in bytes of an encoding of n source bits
|
||||||
|
* @param base58_string the string
|
||||||
|
* @returns the maximum size in bytes had the string been decoded
|
||||||
|
*/
|
||||||
|
size_t libp2p_crypto_encoding_base58_decode_max_size(const unsigned char* base58_string) {
|
||||||
|
size_t string_length = strlen((char*)base58_string);
|
||||||
|
size_t decoded_length = 0;
|
||||||
|
size_t radix = strlen(b58digits_ordered);
|
||||||
|
double bits_per_digit = log2(radix);
|
||||||
|
|
||||||
|
decoded_length = ceil(string_length * bits_per_digit / 8);
|
||||||
|
return decoded_length;
|
||||||
|
}
|
47
base58.h
Normal file
47
base58.h
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
//
|
||||||
|
// base58.h
|
||||||
|
// libp2p_xcode
|
||||||
|
//
|
||||||
|
// Created by John Jones on 11/7/16.
|
||||||
|
// Copyright © 2016 JMJAtlanta. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef base58_h
|
||||||
|
#define base58_h
|
||||||
|
#include "varint.h"
|
||||||
|
/**
|
||||||
|
* convert a base58 encoded string into a binary array
|
||||||
|
* @param base58 the base58 encoded string
|
||||||
|
* @param base58_size the size of the encoded string
|
||||||
|
* @param binary_data the results buffer
|
||||||
|
* @param binary_data_size the size of the results buffer
|
||||||
|
* @returns true(1) on success
|
||||||
|
*/
|
||||||
|
int libp2p_crypto_encoding_base58_decode(const unsigned char* base58, size_t base58_size, unsigned char** binary_data, size_t *binary_data_size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* encode an array of bytes into a base58 string
|
||||||
|
* @param binary_data the data to be encoded
|
||||||
|
* @param binary_data_size the size of the data to be encoded
|
||||||
|
* @param base58 the results buffer
|
||||||
|
* @param base58_size the size of the results buffer
|
||||||
|
* @returns true(1) on success
|
||||||
|
*/
|
||||||
|
int libp2p_crypto_encoding_base58_encode(const unsigned char* binary_data, size_t binary_data_size, unsigned char** base58, size_t* base58_size);
|
||||||
|
|
||||||
|
/***
|
||||||
|
* calculate the size of the binary results based on an incoming base58 string with no initial padding
|
||||||
|
* @param base58_string the string
|
||||||
|
* @returns the size in bytes had the string been decoded
|
||||||
|
*/
|
||||||
|
size_t libp2p_crypto_encoding_base58_decode_size(const unsigned char* base58_string);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* calculate the max length in bytes of an encoding of n source bits
|
||||||
|
* @param base58_string the string
|
||||||
|
* @returns the maximum size in bytes had the string been decoded
|
||||||
|
*/
|
||||||
|
size_t libp2p_crypto_encoding_base58_decode_max_size(const unsigned char* base58_string);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* base58_h */
|
49
ipld.h
49
ipld.h
|
@ -5,12 +5,13 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <jansson.h>
|
#include <jansson.h>
|
||||||
|
#include "base58.h"
|
||||||
|
#include "varhexutils.h"
|
||||||
//Predefined values:
|
//Predefined values:
|
||||||
#define IDKey "@id"
|
#define IDKey "@id"
|
||||||
#define TypeKey "@type"
|
#define TypeKey "@type"
|
||||||
#define ValueKey "@value"
|
#define ValueKey "@value"
|
||||||
#define CtxKey "@context"
|
#define CtxKey "@/home/xethyrion/Desktop/Bak/varint.hcontext"
|
||||||
#define CodecKey "@codec"
|
#define CodecKey "@codec"
|
||||||
#define LinkKey "mlink"
|
#define LinkKey "mlink"
|
||||||
|
|
||||||
|
@ -28,7 +29,7 @@ struct NODE
|
||||||
/* LOAD_NODE(@param1)
|
/* LOAD_NODE(@param1)
|
||||||
* Creates a new node from a string.
|
* Creates a new node from a string.
|
||||||
* @Param1 a json string(char *)
|
* @Param1 a json string(char *)
|
||||||
* returns a json_t object! (jansson.h)
|
* returns a json_t /home/xethyrion/Desktop/Bak/varint.hobject! (jansson.h)
|
||||||
*/
|
*/
|
||||||
struct NODE LOAD_NODE(char * str)
|
struct NODE LOAD_NODE(char * str)
|
||||||
{
|
{
|
||||||
|
@ -275,9 +276,9 @@ void lType(char * str, struct LINK O)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* lType(@param1,@param2)
|
/* lHash(@param1,@param2)
|
||||||
* Gets the type of the link, of course, it should be an mlink.
|
* Gets the hash of the link, not b58 decoded
|
||||||
* @param1: LINK.type //Storing in type from LINK struct.
|
* @param1: LINK.hash //Storing in hash from LINK struct.
|
||||||
* @param2: LINK // The link structure we are using.
|
* @param2: LINK // The link structure we are using.
|
||||||
*/
|
*/
|
||||||
void lHash(char * str, struct LINK O)
|
void lHash(char * str, struct LINK O)
|
||||||
|
@ -323,7 +324,40 @@ void lName(char * str, struct LINK O)
|
||||||
strcat(str, key);
|
strcat(str, key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*B58Hash(@param1, @parunsigned char** binary_dataam2)
|
||||||
|
*Decodes the hash, and stores it into a char from your link struct
|
||||||
|
*/
|
||||||
|
void lb58Hash(char * str, struct LINK X) //Need to find out if prefixed or not!
|
||||||
|
{
|
||||||
|
char * hash = X.hash;
|
||||||
|
size_t hash_length = strlen(hash);
|
||||||
|
size_t result_buffer_length = libp2p_crypto_encoding_base58_decode_max_size(hash);
|
||||||
|
unsigned char result_buffer[result_buffer_length];
|
||||||
|
unsigned char * ptr_2_result = result_buffer;
|
||||||
|
memset(result_buffer, 0, result_buffer_length);
|
||||||
|
int valid = libp2p_crypto_encoding_base58_decode(hash,hash_length,&ptr_2_result, &result_buffer_length);
|
||||||
|
printf("IS_VALID: %d\n",valid);
|
||||||
|
char HReadable[1000];
|
||||||
|
bzero(HReadable,1000);
|
||||||
|
int ilen = 0;
|
||||||
|
for(int i = 0; i<result_buffer_length;i++)
|
||||||
|
{
|
||||||
|
unsigned char c = ptr_2_result[i];
|
||||||
|
char miu[3];
|
||||||
|
bzero(miu,3);
|
||||||
|
sprintf(miu,"%02x",c);
|
||||||
|
miu[3] = '\0';
|
||||||
|
strcat(HReadable, miu);
|
||||||
|
}
|
||||||
|
//DEBUG
|
||||||
|
if(NODE_H_DEBUG == 1)
|
||||||
|
{
|
||||||
|
printf("Normal hash: %s\n", hash);
|
||||||
|
printf("Result: %s\n", HReadable);
|
||||||
|
}
|
||||||
|
strcat(str, HReadable);
|
||||||
|
|
||||||
|
}
|
||||||
/* LOAD_LINK(@param1)
|
/* LOAD_LINK(@param1)
|
||||||
* Creates a new LINK from a string.
|
* Creates a new LINK from a string.
|
||||||
* @Param1 a json string(char *)
|
* @Param1 a json string(char *)
|
||||||
|
@ -344,6 +378,7 @@ struct LINK LOAD_LINK(char * str)
|
||||||
lName(X.name, X);
|
lName(X.name, X);
|
||||||
lType(X.type, X);
|
lType(X.type, X);
|
||||||
lHash(X.hash, X);
|
lHash(X.hash, X);
|
||||||
|
lb58Hash(X.b58hash, X);
|
||||||
return X;
|
return X;
|
||||||
}
|
}
|
||||||
/* Unload_LINK(@param1) - Same as unload_node, makes it easier to avoid leaks and better structuring of your programs
|
/* Unload_LINK(@param1) - Same as unload_node, makes it easier to avoid leaks and better structuring of your programs
|
||||||
|
|
69
ipld_tut.c
Normal file
69
ipld_tut.c
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
#include "ipld.h"
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
//TURN DEBUG MODE ON/OFF
|
||||||
|
NODE_H_DEBUG = 0;
|
||||||
|
|
||||||
|
//Load a node from string:
|
||||||
|
char * str = "{\"@context\": \"/ipfs/Qmf1ec6n9f8kW8JTLjqaZceJVpDpZD4L3aPoJFvssBE7Eb/merkleweb\", \"@type\": \"node\", \"FIELD1\": { \"@value\": \"Qmf1ec6n9f8kW8JTLjqaZceJVpDpZD4L3aPoJFvssBE7Eb\", \"@type\": \"mlink\" }, \"FIELD2\": { \"@value\": \"Qmf1ec6n9f8kW8JTLjqaZceJVpDpZD4L3aPoJFvssBE7Eb\", \"@type\": \"mlink\" } }";
|
||||||
|
struct NODE A;
|
||||||
|
A = LOAD_NODE(str);
|
||||||
|
|
||||||
|
//Get node contents back to a string:
|
||||||
|
char * lol;
|
||||||
|
lol = json_dumps(A.obj, JSON_INDENT(1) | JSON_PRESERVE_ORDER);
|
||||||
|
printf("NODE CONTENTS: \n------------\n%s\n------------\n", lol);
|
||||||
|
free(lol); // Never forget to free the char * after being done with it.
|
||||||
|
|
||||||
|
//Get type of node, if any.
|
||||||
|
char typeget[1000]; //Way bigger than needed.
|
||||||
|
bzero(typeget,1000); //No mem errors ofc.
|
||||||
|
nType(typeget, A.obj);//Check for type if any
|
||||||
|
printf("type: %s\n", typeget);
|
||||||
|
|
||||||
|
//Get context of node.
|
||||||
|
char ctxget[1000]; //Way bigger than needed
|
||||||
|
bzero(ctxget, 1000);
|
||||||
|
nContext(ctxget, A.obj);
|
||||||
|
printf("ctx: %s\n", ctxget);
|
||||||
|
|
||||||
|
//Extracting Links
|
||||||
|
char * links[666];
|
||||||
|
for(int i=0;i<666;i++){ links[i] = NULL;}
|
||||||
|
size_t linknum;
|
||||||
|
linknum = nLinks(links, A.obj); //These all need to be freed, hence the linknum!
|
||||||
|
printf("Linknum: %lu\n", linknum);
|
||||||
|
for(int i=0; i<linknum; i++)
|
||||||
|
{
|
||||||
|
printf("AT %d %s\n",i,links[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Store links in an more accessible version:
|
||||||
|
struct LINK L;
|
||||||
|
L = LOAD_LINK(links[0]);
|
||||||
|
|
||||||
|
//By now you already have easy access to everything, the key name, the hash, the b58 decoded hash, the type.
|
||||||
|
//It will reject any links which aren't of type "mlink", you should check this by seeing if it returns valid or not.
|
||||||
|
char * linkstr;
|
||||||
|
linkstr = json_dumps(L.obj, JSON_INDENT(1) | JSON_PRESERVE_ORDER);
|
||||||
|
printf("LINK CONTENTS: \n------------\n%s\n------------\n", linkstr);
|
||||||
|
free(linkstr);
|
||||||
|
//Access Name
|
||||||
|
printf("LINK NAME:\t%s\n", L.name);
|
||||||
|
|
||||||
|
//Access Type
|
||||||
|
printf("LINK TYPE:\t%s\n", L.type);
|
||||||
|
|
||||||
|
//Access Hash
|
||||||
|
printf("LINK HASH:\t%s\n", L.hash);
|
||||||
|
|
||||||
|
//Access b58Hash
|
||||||
|
printf("LINK B58HASH:\t%s\n", L.b58hash);
|
||||||
|
|
||||||
|
//Free all nodes, links, link pointer array
|
||||||
|
for(int i=0; i<linknum;i++){free(links[i]);} //FREE(Link char pointer array)
|
||||||
|
UNLOAD_LINK(L); // FREE LINK STRUCTURE
|
||||||
|
UNLOAD_NODE(A); // FREE NODE STRUCTURE // You could've done this earlier as soon as you didn't need any more.
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
251
varhexutils.h
Normal file
251
varhexutils.h
Normal file
|
@ -0,0 +1,251 @@
|
||||||
|
#ifndef VARHEXUTILS
|
||||||
|
#define VARHEXUTILS
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include "varint.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "endian.h"
|
||||||
|
/*uint8_t * encode_big_endian_32(uint32_t ebex32)
|
||||||
|
{
|
||||||
|
uint8_t encbe[10] = {0};
|
||||||
|
memcpy(encbe, htobe32(ebex32));
|
||||||
|
return encbe;
|
||||||
|
}*/
|
||||||
|
int8_t Var_Bytes_Count(uint8_t * countbytesofthis)
|
||||||
|
{
|
||||||
|
static int8_t xrzk_bytescnt = 0;
|
||||||
|
for(int8_t i=0; i<10; i++)
|
||||||
|
{
|
||||||
|
if(countbytesofthis[i] != 0)
|
||||||
|
{
|
||||||
|
xrzk_bytescnt++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return xrzk_bytescnt;
|
||||||
|
}
|
||||||
|
uint8_t * Num_To_Varint_64(uint64_t TOV64INPUT) //UINT64_T TO VARINT
|
||||||
|
{
|
||||||
|
static uint8_t buffy_001[60] = {0};
|
||||||
|
uvarint_encode64(TOV64INPUT, buffy_001, 60);
|
||||||
|
return buffy_001;
|
||||||
|
}
|
||||||
|
uint8_t * Num_To_Varint_32(uint32_t TOV32INPUT) // UINT32_T TO VARINT
|
||||||
|
{
|
||||||
|
static uint8_t buffy_032[60] = {0};
|
||||||
|
uvarint_encode32(TOV32INPUT, buffy_032, 60);
|
||||||
|
return buffy_032;
|
||||||
|
}
|
||||||
|
uint64_t * Varint_To_Num_64(uint8_t TON64INPUT[60]) //VARINT TO UINT64_t
|
||||||
|
{
|
||||||
|
static uint64_t varintdecode_001 = 0;
|
||||||
|
uvarint_decode64(TON64INPUT, 60, &varintdecode_001);
|
||||||
|
return &varintdecode_001;
|
||||||
|
}
|
||||||
|
uint32_t * Varint_To_Num_32(uint8_t TON32INPUT[60]) //VARINT TO UINT32_t
|
||||||
|
{
|
||||||
|
static uint32_t varintdecode_032 = 0;
|
||||||
|
uvarint_decode32(TON32INPUT, 60, &varintdecode_032);
|
||||||
|
return &varintdecode_032;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
char * Int_To_Hex(uint64_t int2hex) //VAR[binformat] TO HEX
|
||||||
|
{
|
||||||
|
static char int2hex_result[800]="\0";
|
||||||
|
memset(int2hex_result,0,sizeof(int2hex_result));
|
||||||
|
sprintf (int2hex_result, "%02lX", int2hex);
|
||||||
|
return int2hex_result;
|
||||||
|
}
|
||||||
|
uint64_t Hex_To_Int(char * hax)
|
||||||
|
{
|
||||||
|
char * hex = NULL;
|
||||||
|
hex=hax;
|
||||||
|
uint64_t val = 0;
|
||||||
|
while (*hex)
|
||||||
|
{
|
||||||
|
// get current character then increment
|
||||||
|
uint8_t byte = *hex++;
|
||||||
|
// transform hex character to the 4bit equivalent number, using the ascii table indexes
|
||||||
|
if (byte >= '0' && byte <= '9') byte = byte - '0';
|
||||||
|
else if (byte >= 'a' && byte <='f') byte = byte - 'a' + 10;
|
||||||
|
else if (byte >= 'A' && byte <='F') byte = byte - 'A' + 10;
|
||||||
|
// shift 4 to make space for new digit, and add the 4 bits of the new digit
|
||||||
|
val = (val << 4) | (byte & 0xF);
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
void vthconvert(int size, char * crrz01, uint8_t * xbuf)
|
||||||
|
{
|
||||||
|
uint8_t buf[400];
|
||||||
|
bzero(buf,400);
|
||||||
|
|
||||||
|
//fixing the buf
|
||||||
|
for(int cz=0; cz<size;cz++)
|
||||||
|
{
|
||||||
|
buf[cz] = xbuf[cz];
|
||||||
|
}
|
||||||
|
//
|
||||||
|
if(crrz01!=NULL)
|
||||||
|
{
|
||||||
|
char * crrz1 = NULL;
|
||||||
|
crrz1 = crrz01;
|
||||||
|
char conv_proc[800]="\0";
|
||||||
|
int i;
|
||||||
|
for(i=0; i < (size*2); i++)
|
||||||
|
{
|
||||||
|
if(buf[i]!='\0')
|
||||||
|
{
|
||||||
|
sprintf (conv_proc, "%02X", buf[i]);
|
||||||
|
//printf("%d:%d\n",i, buf[i]);
|
||||||
|
strcat(crrz1, conv_proc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
crrz1 = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
char * Var_To_Hex(int realsize, uint8_t * TOHEXINPUT) //VAR[binformat] TO HEX
|
||||||
|
{
|
||||||
|
for(int ix=realsize;ix<400;ix++)
|
||||||
|
{
|
||||||
|
TOHEXINPUT[ix] = '\0';
|
||||||
|
}
|
||||||
|
if(TOHEXINPUT != NULL)
|
||||||
|
{
|
||||||
|
static char convert_resultz1[800]="\0";
|
||||||
|
bzero(convert_resultz1,800);
|
||||||
|
vthconvert(realsize, convert_resultz1, TOHEXINPUT);
|
||||||
|
return convert_resultz1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uint8_t * Hex_To_Var(char * Hexstr) //HEX TO VAR[BINFORMAT]
|
||||||
|
{
|
||||||
|
static uint8_t buffy_HEX[400] = {0};
|
||||||
|
bzero(buffy_HEX,400);
|
||||||
|
int i;
|
||||||
|
char codo[800] = "\0";
|
||||||
|
bzero(codo,800);
|
||||||
|
strcpy(codo, Hexstr);
|
||||||
|
char code[3];
|
||||||
|
bzero(code,3);
|
||||||
|
code[3]='\0';
|
||||||
|
int x = 0;
|
||||||
|
int fori001=0;
|
||||||
|
for(fori001=0;fori001<800;fori001++)
|
||||||
|
{
|
||||||
|
strncpy(&code[0],&codo[fori001],1);
|
||||||
|
strncpy(&code[1],&codo[fori001+1],1);
|
||||||
|
char *ck = NULL;
|
||||||
|
uint64_t lu = 0;
|
||||||
|
lu=strtoul(code, &ck, 16);
|
||||||
|
buffy_HEX[x] = lu;
|
||||||
|
//printf("%s - %lu\n",code,lu);
|
||||||
|
fori001++;
|
||||||
|
x++;
|
||||||
|
}
|
||||||
|
return buffy_HEX;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
void convert(char * convert_result, uint8_t * buf) //Both of them read them properly.
|
||||||
|
{
|
||||||
|
char conv_proc[800]="\0";
|
||||||
|
bzero(conv_proc,800);
|
||||||
|
int i;
|
||||||
|
for(i=0; i < 10; i++)
|
||||||
|
{
|
||||||
|
sprintf (conv_proc, "%02X", buf[i]);
|
||||||
|
//printf("%d:%d\n",i, buf[i]);
|
||||||
|
strcat(convert_result, conv_proc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
char * Num_To_HexVar_64(uint64_t TOHVINPUT) //UINT64 TO HEXIFIED VAR
|
||||||
|
{ //Code to varint - py
|
||||||
|
static char convert_result[800]="\0";//Note that the hex resulted from this will differ from py
|
||||||
|
bzero(convert_result,800);
|
||||||
|
memset(convert_result,0,sizeof(convert_result));//But if you make sure the string is always 20 chars in size
|
||||||
|
uint8_t buf[400] = {0};
|
||||||
|
bzero(buf,400);
|
||||||
|
uvarint_encode64(TOHVINPUT, buf, 800);
|
||||||
|
convert(convert_result,buf);
|
||||||
|
return convert_result;
|
||||||
|
}
|
||||||
|
void convert2(char * convert_result2, uint8_t * bufhx)
|
||||||
|
{
|
||||||
|
uint8_t * buf = NULL;
|
||||||
|
buf = bufhx;
|
||||||
|
char conv_proc[3]="\0";
|
||||||
|
conv_proc[3] = '\0';
|
||||||
|
bzero(conv_proc, 3);
|
||||||
|
int i;
|
||||||
|
for(i=0; i == 0; i++)
|
||||||
|
{
|
||||||
|
sprintf (conv_proc, "%02X", buf[i]);
|
||||||
|
//printf("aaaaaaaaaaah%d:%d\n",i, buf[i]);
|
||||||
|
strcat(convert_result2, conv_proc);
|
||||||
|
}
|
||||||
|
buf = NULL;
|
||||||
|
}
|
||||||
|
char * Num_To_HexVar_32(uint32_t TOHVINPUT) //UINT32 TO HEXIFIED VAR
|
||||||
|
{ //Code to varint - py
|
||||||
|
static char convert_result2[3]="\0";
|
||||||
|
bzero(convert_result2,3);
|
||||||
|
convert_result2[2] = '\0';
|
||||||
|
memset(convert_result2,0,sizeof(convert_result2));
|
||||||
|
uint8_t buf[1] = {0};
|
||||||
|
bzero(buf,1);
|
||||||
|
uvarint_encode32(TOHVINPUT, buf, 1);
|
||||||
|
convert2(convert_result2,buf);
|
||||||
|
return convert_result2;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t HexVar_To_Num_64(char * theHEXstring) //HEXIFIED VAR TO UINT64_T
|
||||||
|
{ //Varint to code - py
|
||||||
|
uint8_t buffy[400] = {0};
|
||||||
|
char codo[800] = "\0";
|
||||||
|
bzero(codo,800);
|
||||||
|
strcpy(codo, theHEXstring);
|
||||||
|
char code[3] = "\0";
|
||||||
|
int x = 0;
|
||||||
|
for(int i= 0;i<399;i++)
|
||||||
|
{
|
||||||
|
strncpy(&code[0],&codo[i],1);
|
||||||
|
strncpy(&code[1],&codo[i+1],1);
|
||||||
|
char *ck = NULL;
|
||||||
|
uint64_t lu = 0;
|
||||||
|
lu=strtoul(code, &ck, 16);
|
||||||
|
buffy[x] = lu;
|
||||||
|
i++;
|
||||||
|
x++;
|
||||||
|
}
|
||||||
|
static uint64_t decoded;
|
||||||
|
uvarint_decode64 (buffy, 400, &decoded);
|
||||||
|
return decoded;
|
||||||
|
}
|
||||||
|
uint32_t HexVar_To_Num_32(char theHEXstring[]) //HEXIFIED VAR TO UINT32_T
|
||||||
|
{ //Varint to code py
|
||||||
|
uint8_t buffy[400] = {0};
|
||||||
|
bzero(buffy,400);
|
||||||
|
char codo[800] = "\0";
|
||||||
|
bzero(codo,800);
|
||||||
|
strcpy(codo, theHEXstring);
|
||||||
|
char code[3] = "\0";
|
||||||
|
bzero(code,3);
|
||||||
|
code[3] = '\0';
|
||||||
|
int x = 0;
|
||||||
|
for(int i= 0;i<399;i++)
|
||||||
|
{
|
||||||
|
strncpy(&code[0],&codo[i],1);
|
||||||
|
strncpy(&code[1],&codo[i+1],1);
|
||||||
|
char *ck = NULL;
|
||||||
|
uint32_t lu = {0};
|
||||||
|
lu=strtoul(code, &ck, 16);
|
||||||
|
buffy[x] = lu;
|
||||||
|
i++;
|
||||||
|
x++;
|
||||||
|
}
|
||||||
|
static uint32_t decoded;
|
||||||
|
uvarint_decode32 (buffy, 10, &decoded);
|
||||||
|
return decoded;
|
||||||
|
}
|
||||||
|
#endif
|
8
varint.c
Normal file
8
varint.c
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#include "varint.h"
|
||||||
|
|
||||||
|
|
||||||
|
DEFN_ENCODER(32)
|
||||||
|
DEFN_DECODER(32)
|
||||||
|
|
||||||
|
DEFN_ENCODER(64)
|
||||||
|
DEFN_DECODER(64)
|
51
varint.h
Normal file
51
varint.h
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
#ifndef VARINT
|
||||||
|
#define VARINT
|
||||||
|
#include <stddef.h> /* size_t */
|
||||||
|
#include <stdint.h> /* uint8_t, uint64_t */
|
||||||
|
|
||||||
|
|
||||||
|
#define DEFN_ENCODER(SIZE) \
|
||||||
|
size_t \
|
||||||
|
uvarint_encode##SIZE (uint##SIZE##_t val, uint8_t buf[], size_t bufsize) \
|
||||||
|
{ \
|
||||||
|
size_t i = 0; \
|
||||||
|
for (; i < (SIZE/8) && i < bufsize; i++) { \
|
||||||
|
buf[i] = (uint8_t) ((val & 0xFF) | 0x80); \
|
||||||
|
val >>= 7; \
|
||||||
|
if (!val) \
|
||||||
|
return i + 1; \
|
||||||
|
} \
|
||||||
|
return -1; \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define DEFN_DECODER(SIZE) \
|
||||||
|
size_t \
|
||||||
|
uvarint_decode##SIZE (uint8_t buf[], size_t bufsize, uint##SIZE##_t *val) \
|
||||||
|
{ \
|
||||||
|
*val = 0; \
|
||||||
|
size_t i = 0; \
|
||||||
|
for (; i < (SIZE/8) && i < bufsize; i++) { \
|
||||||
|
*val |= ((buf[i] & 0x7f) << (7 * i)); \
|
||||||
|
if (!(buf[i] & 0x80)) \
|
||||||
|
return i + 1; \
|
||||||
|
} \
|
||||||
|
return -1; \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define DECL_ENCODER(SIZE) \
|
||||||
|
size_t \
|
||||||
|
uvarint_encode##SIZE (uint##SIZE##_t val, uint8_t buf[], size_t bufsize);
|
||||||
|
|
||||||
|
#define DECL_DECODER(SIZE) \
|
||||||
|
size_t \
|
||||||
|
uvarint_decode##SIZE (uint8_t buf[], size_t bufsize, uint##SIZE##_t *val);
|
||||||
|
|
||||||
|
|
||||||
|
DECL_ENCODER(32)
|
||||||
|
DECL_DECODER(32)
|
||||||
|
|
||||||
|
DECL_ENCODER(64)
|
||||||
|
DECL_DECODER(64)
|
||||||
|
#endif
|
Loading…
Reference in a new issue