suidouble 0.0.15 → 0.0.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/lib/SuiCliCommands.js +32 -6
- package/lib/SuiInBrowser.js +1 -1
- package/lib/SuiLocalTestValidator.js +41 -2
- package/lib/SuiMaster.js +15 -4
- package/package.json +1 -1
- package/test/sui_in_browser.test.js +65 -0
- package/test/sui_master_onlocal.test.js +2 -2
- package/test/test_move_contracts/suidouble_color/Move.lock +20 -0
- package/test/test_move_contracts/suidouble_color/Move.toml +10 -0
- package/test/test_move_contracts/suidouble_color/sources/suidouble_color.move +150 -0
package/README.md
CHANGED
|
@@ -17,6 +17,7 @@ Set of provider, package and object classes for javascript representation of Sui
|
|
|
17
17
|
- [Connecting web3 dapps to Sui](#sui-move-connect-in-browser)
|
|
18
18
|
- [Todo](#todo)
|
|
19
19
|
|
|
20
|
+
Also take a look at sample Vue dapp application [source code](https://github.com/suidouble/suidouble-sample-app) or [check it online](https://suidouble-sample-app.herokuapp.com/).
|
|
20
21
|
|
|
21
22
|
### installation
|
|
22
23
|
|
|
@@ -304,6 +305,15 @@ suiInBrowser.addEventListener('connected', async()=>{
|
|
|
304
305
|
|
|
305
306
|
```
|
|
306
307
|
|
|
308
|
+
### Unit tests
|
|
309
|
+
|
|
310
|
+
```bash
|
|
311
|
+
npm install
|
|
312
|
+
npm run tests
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
Take a look at [unit tests](test) code for some inspiration.
|
|
316
|
+
|
|
307
317
|
### Todo
|
|
308
318
|
|
|
309
319
|
- subscribe to events
|
package/lib/SuiCliCommands.js
CHANGED
|
@@ -20,14 +20,40 @@ class SuiCliCommands {
|
|
|
20
20
|
throw new Error('can not spawn a proccess in this env');
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
return await new Promise((res,rej)=>{
|
|
24
|
+
let success = true;
|
|
25
|
+
let e = null;
|
|
26
|
+
const proc = doSpawn(command, [], {
|
|
27
|
+
env: {
|
|
28
|
+
...process.env,
|
|
29
|
+
...envVars,
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
proc.on('error', function(err) {
|
|
33
|
+
success = false;
|
|
34
|
+
e = err;
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
setTimeout(()=>{
|
|
38
|
+
if (success) {
|
|
39
|
+
res(proc);
|
|
40
|
+
} else {
|
|
41
|
+
rej(e);
|
|
42
|
+
}
|
|
43
|
+
}, 100);
|
|
28
44
|
});
|
|
29
45
|
|
|
30
|
-
|
|
46
|
+
// const proc = doSpawn(command, [], {
|
|
47
|
+
// env: {
|
|
48
|
+
// ...process.env,
|
|
49
|
+
// ...envVars,
|
|
50
|
+
// }
|
|
51
|
+
// });
|
|
52
|
+
// proc.on('error', function(err) {
|
|
53
|
+
// console.log('Oh noez, teh errurz: ' + err);
|
|
54
|
+
// });
|
|
55
|
+
|
|
56
|
+
// return proc;
|
|
31
57
|
}
|
|
32
58
|
|
|
33
59
|
static async exec(command) {
|
package/lib/SuiInBrowser.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// const { spawn } = require('child_process');
|
|
2
2
|
const SuiCliCommands = require('./SuiCliCommands.js');
|
|
3
3
|
const SuiCommonMethods = require('./SuiCommonMethods.js');
|
|
4
|
+
const { JsonRpcProvider, localnetConnection, devnetConnection } = require('@mysten/sui.js');
|
|
4
5
|
|
|
5
6
|
class SuiLocalTestValidator extends SuiCommonMethods {
|
|
6
7
|
constructor(params = {}) {
|
|
@@ -8,6 +9,28 @@ class SuiLocalTestValidator extends SuiCommonMethods {
|
|
|
8
9
|
|
|
9
10
|
this._child = null;
|
|
10
11
|
this._active = false;
|
|
12
|
+
|
|
13
|
+
this._testFallbackEnabled = false;
|
|
14
|
+
if (params.testFallbackEnabled) {
|
|
15
|
+
// option for unit tests to fallback to sui:dev network in case
|
|
16
|
+
// there is no local validator installed
|
|
17
|
+
this._testFallbackEnabled = true;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
this._providerName = 'sui:localnet';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
get providerName() {
|
|
24
|
+
return this._providerName;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
get provider() {
|
|
28
|
+
if (this._providerName === 'sui:localnet') {
|
|
29
|
+
return new JsonRpcProvider(localnetConnection);
|
|
30
|
+
} else if (this._providerName === 'sui:devnet') {
|
|
31
|
+
// if testFallbackEnabled == true and we can't start local node
|
|
32
|
+
return new JsonRpcProvider(devnetConnection);
|
|
33
|
+
}
|
|
11
34
|
}
|
|
12
35
|
|
|
13
36
|
get active() {
|
|
@@ -30,13 +53,28 @@ class SuiLocalTestValidator extends SuiCommonMethods {
|
|
|
30
53
|
}
|
|
31
54
|
|
|
32
55
|
async launch() {
|
|
33
|
-
if (this.
|
|
56
|
+
if (this._active) {
|
|
34
57
|
return this;
|
|
35
58
|
}
|
|
36
59
|
|
|
37
60
|
this.log('launching sui-test-validator ...');
|
|
38
61
|
|
|
39
|
-
|
|
62
|
+
try {
|
|
63
|
+
this._child = await SuiCliCommands.spawn('sui-test-validator', { RUST_LOG: 'consensus=off' });
|
|
64
|
+
} catch (e) {
|
|
65
|
+
if (this._testFallbackEnabled) {
|
|
66
|
+
// can't start local node. Let's switch to sui:dev
|
|
67
|
+
this.log('can not start local node. Fallback to sui:dev...');
|
|
68
|
+
|
|
69
|
+
this._child = null;
|
|
70
|
+
this._active = true;
|
|
71
|
+
this._providerName = 'sui:devnet';
|
|
72
|
+
|
|
73
|
+
return this;
|
|
74
|
+
} else {
|
|
75
|
+
throw e;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
40
78
|
|
|
41
79
|
this.__readyLaunchedPromiseResolver = null;
|
|
42
80
|
this.__readyLaunchedPromise = new Promise((res)=>{
|
|
@@ -67,6 +105,7 @@ class SuiLocalTestValidator extends SuiCommonMethods {
|
|
|
67
105
|
});
|
|
68
106
|
|
|
69
107
|
process.on('exit', ()=>{
|
|
108
|
+
console.log('this._testFallbackEnabled', this._testFallbackEnabled);
|
|
70
109
|
if (this._child) {
|
|
71
110
|
this._child.kill();
|
|
72
111
|
}
|
package/lib/SuiMaster.js
CHANGED
|
@@ -15,8 +15,13 @@ class SuiMaster extends SuiCommonMethods {
|
|
|
15
15
|
this._signer = null;
|
|
16
16
|
this._keypair = null;
|
|
17
17
|
|
|
18
|
+
this._address = null;
|
|
19
|
+
|
|
18
20
|
if (params.signer) {
|
|
19
21
|
this._signer = params.signer;
|
|
22
|
+
if (this._signer && this._signer.connectedAddress) {
|
|
23
|
+
this._address = this._signer.connectedAddress;
|
|
24
|
+
}
|
|
20
25
|
} else if (params.keypair) {
|
|
21
26
|
this._keypair = params.keypair;
|
|
22
27
|
} else if (params.phrase) {
|
|
@@ -34,8 +39,16 @@ class SuiMaster extends SuiCommonMethods {
|
|
|
34
39
|
this._providerName = null;
|
|
35
40
|
if (params.provider) {
|
|
36
41
|
if (params.provider == 'local' || (params.provider.constructor && params.provider.constructor.name && params.provider.constructor.name == 'SuiLocalTestValidator')) {
|
|
37
|
-
|
|
38
|
-
|
|
42
|
+
if (params.provider == 'local') {
|
|
43
|
+
this._provider = new sui.JsonRpcProvider(sui.localnetConnection);
|
|
44
|
+
this._providerName = 'sui:localnet';
|
|
45
|
+
} else {
|
|
46
|
+
// SuiLocalTestValidator
|
|
47
|
+
this._providerName = params.provider.providerName;
|
|
48
|
+
this._provider = params.provider.provider;
|
|
49
|
+
}
|
|
50
|
+
// this._provider = new sui.JsonRpcProvider(sui.localnetConnection);
|
|
51
|
+
// this._providerName = 'sui:localnet';
|
|
39
52
|
} else if (params.provider == 'test' || params.provider == 'testnet') {
|
|
40
53
|
this._provider = new sui.JsonRpcProvider(sui.testnetConnection);
|
|
41
54
|
this._providerName = 'sui:testnet';
|
|
@@ -78,8 +91,6 @@ class SuiMaster extends SuiCommonMethods {
|
|
|
78
91
|
|
|
79
92
|
this._initialized = false;
|
|
80
93
|
|
|
81
|
-
this._address = null;
|
|
82
|
-
|
|
83
94
|
this._packages = {};
|
|
84
95
|
}
|
|
85
96
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "suidouble",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.17",
|
|
4
4
|
"description": "Set of provider, package and object classes for javascript representation of Sui Move smart contracts. Use same code for publishing, upgrading, integration testing, interaction with smart contracts and integration in browser web3 dapps",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
// just a basic test of InBrowser classes. No real interaction, just structure and events
|
|
4
|
+
|
|
5
|
+
const t = require('tap');
|
|
6
|
+
const { test } = t;
|
|
7
|
+
|
|
8
|
+
const { SuiInBrowser } = require('..');
|
|
9
|
+
|
|
10
|
+
test('as single instance', async t => {
|
|
11
|
+
// probably you'd want a single instance of SuiInBrowser class on your dapp,
|
|
12
|
+
// so initialize it via class' static method:
|
|
13
|
+
const suiInBrowser = SuiInBrowser.getSingleton();
|
|
14
|
+
const suiInBrowserCopy = SuiInBrowser.getSingleton();
|
|
15
|
+
|
|
16
|
+
t.equal(suiInBrowser, suiInBrowserCopy);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test('initialization', async t => {
|
|
20
|
+
const suiInBrowser = new SuiInBrowser({});
|
|
21
|
+
|
|
22
|
+
t.ok(suiInBrowser);
|
|
23
|
+
|
|
24
|
+
const gotAdapters = [];
|
|
25
|
+
// it should emit 'adapter' events, even though they are not installed (remember, we are in node.js now)
|
|
26
|
+
// adapter has propery of .isInstalled
|
|
27
|
+
suiInBrowser.addEventListener('adapter', (e)=>{
|
|
28
|
+
gotAdapters.push(e.detail);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// emit is not instant, but on *nextTick*
|
|
32
|
+
await new Promise((res)=>setTimeout(res, 100));
|
|
33
|
+
|
|
34
|
+
t.ok(gotAdapters.length > 0);
|
|
35
|
+
|
|
36
|
+
const suiWalletAdapter = gotAdapters.find((adapter)=>(adapter.name == 'Sui Wallet')); // there're few, but lets test one
|
|
37
|
+
|
|
38
|
+
t.ok(suiWalletAdapter);
|
|
39
|
+
|
|
40
|
+
t.equal(suiWalletAdapter.name, 'Sui Wallet');
|
|
41
|
+
t.ok(!suiWalletAdapter.isInstalled);
|
|
42
|
+
t.ok(suiWalletAdapter.icon);
|
|
43
|
+
t.ok(suiWalletAdapter.icon.indexOf('data:image/') != -1); // icon is data-url
|
|
44
|
+
|
|
45
|
+
t.ok(suiWalletAdapter.getDownloadURL()); // url to install extension
|
|
46
|
+
t.ok(suiWalletAdapter.getDownloadURL().indexOf('https://') != -1);
|
|
47
|
+
|
|
48
|
+
// we can get instance of suiMaster out of suiInBrowser even if we are not connected to wallet
|
|
49
|
+
// it will work without signer, but you can read data from chain
|
|
50
|
+
const suiMaster = await suiInBrowser.getSuiMaster();
|
|
51
|
+
|
|
52
|
+
t.ok(suiMaster);
|
|
53
|
+
t.ok(!suiMaster.connectedAddress); // nothing
|
|
54
|
+
t.ok(suiMaster.connectedChain); // but there's chain
|
|
55
|
+
|
|
56
|
+
// by default, SuiInBrowser gets you devnet connection (it's overloaded by Wallet Extension current chain)
|
|
57
|
+
t.equal(suiMaster.connectedChain, 'sui:devnet');
|
|
58
|
+
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test('initialization via mainnet', async t => {
|
|
62
|
+
const suiInBrowser = new SuiInBrowser({defaultChain: 'sui:mainnet'});
|
|
63
|
+
const suiMaster = await suiInBrowser.getSuiMaster();
|
|
64
|
+
t.equal(suiMaster.connectedChain, 'sui:mainnet');
|
|
65
|
+
});
|
|
@@ -16,7 +16,7 @@ let contractAddressV2 = null;
|
|
|
16
16
|
let chatShopObjectId = null;
|
|
17
17
|
|
|
18
18
|
test('spawn local test node', async t => {
|
|
19
|
-
suiLocalTestValidator = await SuiLocalTestValidator.launch();
|
|
19
|
+
suiLocalTestValidator = await SuiLocalTestValidator.launch({ testFallbackEnabled: true });
|
|
20
20
|
t.ok(suiLocalTestValidator.active);
|
|
21
21
|
|
|
22
22
|
// SuiLocalTestValidator runs as signle instance. So you can't start it twice with static method
|
|
@@ -25,7 +25,7 @@ test('spawn local test node', async t => {
|
|
|
25
25
|
});
|
|
26
26
|
|
|
27
27
|
test('init suiMaster and connect it to local test validator', async t => {
|
|
28
|
-
suiMaster = new SuiMaster({provider: suiLocalTestValidator, as: 'somebody'});
|
|
28
|
+
suiMaster = new SuiMaster({provider: suiLocalTestValidator, as: 'somebody', debug: false});
|
|
29
29
|
await suiMaster.initialize();
|
|
30
30
|
|
|
31
31
|
t.ok(suiMaster.address); // there should be some address
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# @generated by Move, please check-in and do not edit manually.
|
|
2
|
+
|
|
3
|
+
[move]
|
|
4
|
+
version = 0
|
|
5
|
+
|
|
6
|
+
dependencies = [
|
|
7
|
+
{ name = "Sui" },
|
|
8
|
+
]
|
|
9
|
+
|
|
10
|
+
[[move.package]]
|
|
11
|
+
name = "MoveStdlib"
|
|
12
|
+
source = { git = "https://github.com/MystenLabs/sui.git", rev = "testnet", subdir = "crates/sui-framework/packages/move-stdlib" }
|
|
13
|
+
|
|
14
|
+
[[move.package]]
|
|
15
|
+
name = "Sui"
|
|
16
|
+
source = { git = "https://github.com/MystenLabs/sui.git", rev = "testnet", subdir = "crates/sui-framework/packages/sui-framework" }
|
|
17
|
+
|
|
18
|
+
dependencies = [
|
|
19
|
+
{ name = "MoveStdlib" },
|
|
20
|
+
]
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "suidouble_color"
|
|
3
|
+
version = "0.0.1"
|
|
4
|
+
|
|
5
|
+
[dependencies]
|
|
6
|
+
Sui = { git = "https://github.com/MystenLabs/sui.git", subdir = "crates/sui-framework/packages/sui-framework", rev = "testnet" }
|
|
7
|
+
|
|
8
|
+
[addresses]
|
|
9
|
+
suidouble_color = "0x0"
|
|
10
|
+
sui = "0000000000000000000000000000000000000000000000000000000000000002"
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
|
|
2
|
+
module suidouble_color::suidouble_color {
|
|
3
|
+
use sui::tx_context::{Self, sender, TxContext};
|
|
4
|
+
use std::string::{Self, utf8, String};
|
|
5
|
+
use sui::transfer;
|
|
6
|
+
use sui::object::{Self, UID, ID};
|
|
7
|
+
use std::vector::{Self, append, insert};
|
|
8
|
+
|
|
9
|
+
use sui::event::emit;
|
|
10
|
+
|
|
11
|
+
// The creator bundle: these two packages often go together.
|
|
12
|
+
use sui::package;
|
|
13
|
+
use sui::display;
|
|
14
|
+
|
|
15
|
+
/// Text size overflow.
|
|
16
|
+
const EInvalidColor: u64 = 0;
|
|
17
|
+
|
|
18
|
+
// ======== Events =========
|
|
19
|
+
|
|
20
|
+
/// Event. When a new color minted
|
|
21
|
+
struct ColorCreated has copy, drop { id: ID, r: u8, g: u8, b: u8 }
|
|
22
|
+
|
|
23
|
+
/// The Hero - an outstanding collection of digital art.
|
|
24
|
+
struct Color has key, store {
|
|
25
|
+
id: UID,
|
|
26
|
+
name: String,
|
|
27
|
+
r: u8,
|
|
28
|
+
g: u8,
|
|
29
|
+
b: u8,
|
|
30
|
+
img_url: String,
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/// One-Time-Witness for the module.
|
|
34
|
+
struct SUIDOUBLE_COLOR has drop {}
|
|
35
|
+
|
|
36
|
+
/// In the module initializer we claim the `Publisher` object
|
|
37
|
+
/// to then create a `Display`. The `Display` is initialized with
|
|
38
|
+
/// a set of fields (but can be modified later) and published via
|
|
39
|
+
/// the `update_version` call.
|
|
40
|
+
///
|
|
41
|
+
/// Keys and values are set in the initializer but could also be
|
|
42
|
+
/// set after publishing if a `Publisher` object was created.
|
|
43
|
+
fun init(otw: SUIDOUBLE_COLOR, ctx: &mut TxContext) {
|
|
44
|
+
let keys = vector[
|
|
45
|
+
utf8(b"name"),
|
|
46
|
+
utf8(b"link"),
|
|
47
|
+
utf8(b"image_url"),
|
|
48
|
+
utf8(b"description"),
|
|
49
|
+
utf8(b"project_url"),
|
|
50
|
+
utf8(b"creator"),
|
|
51
|
+
];
|
|
52
|
+
|
|
53
|
+
let values = vector[
|
|
54
|
+
utf8(b"{name}"),
|
|
55
|
+
// For `link` we can build a URL using an `id` property
|
|
56
|
+
utf8(b"https://suidouble-color.herokuapp.com/color/{id}"),
|
|
57
|
+
utf8(b"{img_url}"),
|
|
58
|
+
// Description is static for all `Color` objects.
|
|
59
|
+
utf8(b"What a nice color. Isn't it?"),
|
|
60
|
+
// Project URL is usually static
|
|
61
|
+
utf8(b"https://suidouble-color.herokuapp.com/"),
|
|
62
|
+
// Creator field can be any
|
|
63
|
+
utf8(b"Jeka")
|
|
64
|
+
];
|
|
65
|
+
|
|
66
|
+
// Claim the `Publisher` for the package!
|
|
67
|
+
let publisher = package::claim(otw, ctx);
|
|
68
|
+
|
|
69
|
+
// Get a new `Display` object for the `Color` type.
|
|
70
|
+
let display = display::new_with_fields<Color>(
|
|
71
|
+
&publisher, keys, values, ctx
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
// Commit first version of `Display` to apply changes.
|
|
75
|
+
display::update_version(&mut display);
|
|
76
|
+
|
|
77
|
+
transfer::public_transfer(publisher, sender(ctx));
|
|
78
|
+
transfer::public_transfer(display, sender(ctx));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/// Anyone can mint their `Color`!
|
|
82
|
+
public entry fun mint(name: String, r: u8, g: u8, b: u8, ctx: &mut TxContext) {
|
|
83
|
+
assert!(r >= 0 && r <= 255, EInvalidColor);
|
|
84
|
+
assert!(g >= 0 && g <= 255, EInvalidColor);
|
|
85
|
+
assert!(b >= 0 && b <= 255, EInvalidColor);
|
|
86
|
+
|
|
87
|
+
let id = object::new(ctx);
|
|
88
|
+
|
|
89
|
+
emit(ColorCreated { id: object::uid_to_inner(&id), r, g, b, });
|
|
90
|
+
|
|
91
|
+
// constructing the smallest (1x1) GIF with the color of RGB
|
|
92
|
+
let gif_start = vector<u8>[71, 73, 70, 56, 57, 97, 1, 0, 1, 0, 128, 1, 0];
|
|
93
|
+
let gif_end = vector<u8>[0, 0, 0, 33, 249, 4, 1, 10, 0, 1, 0, 44, 0, 0, 0, 0, 1, 0, 1, 0, 0, 2, 2, 68, 1, 0, 59];
|
|
94
|
+
|
|
95
|
+
insert(&mut gif_start, r, 13); // appending R
|
|
96
|
+
insert(&mut gif_start, g, 14); // appending G
|
|
97
|
+
insert(&mut gif_start, b, 15); // appending B
|
|
98
|
+
append(&mut gif_start, gif_end);
|
|
99
|
+
|
|
100
|
+
let img_url = encode(&gif_start);
|
|
101
|
+
|
|
102
|
+
let base_prefix = b"data:image/gif;base64,";
|
|
103
|
+
let as_string = utf8(base_prefix);
|
|
104
|
+
string::append(&mut as_string, utf8(img_url));
|
|
105
|
+
|
|
106
|
+
//
|
|
107
|
+
let color = Color { id, name, img_url: as_string, r: r, g: g, b: b };
|
|
108
|
+
|
|
109
|
+
transfer::transfer(color, tx_context::sender(ctx));
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// thanks to: https://github.com/movefuns/movefuns/blob/dd1f4443c6bf0bc761b27e28fb6ba00f10636840/stdlib/sources/base64.move#L2
|
|
113
|
+
const TABLE: vector<u8> = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
114
|
+
|
|
115
|
+
public fun encode(str: &vector<u8>): vector<u8> {
|
|
116
|
+
if (vector::is_empty(str)) {
|
|
117
|
+
return vector::empty<u8>()
|
|
118
|
+
};
|
|
119
|
+
let size = vector::length(str);
|
|
120
|
+
let eq: u8 = 61;
|
|
121
|
+
let res = vector::empty<u8>();
|
|
122
|
+
|
|
123
|
+
let m = 0 ;
|
|
124
|
+
while (m < size ) {
|
|
125
|
+
vector::push_back(&mut res, *vector::borrow(&TABLE, (((*vector::borrow(str, m) & 0xfc) >> 2) as u64)));
|
|
126
|
+
if ( m + 3 >= size) {
|
|
127
|
+
if ( size % 3 == 1) {
|
|
128
|
+
vector::push_back(&mut res, *vector::borrow(&TABLE, (((*vector::borrow(str, m) & 0x03) << 4) as u64)));
|
|
129
|
+
vector::push_back(&mut res, eq);
|
|
130
|
+
vector::push_back(&mut res, eq);
|
|
131
|
+
}else if (size % 3 == 2) {
|
|
132
|
+
vector::push_back(&mut res, *vector::borrow(&TABLE, ((((*vector::borrow(str, m) & 0x03) << 4) + ((*vector::borrow(str, m + 1) & 0xf0) >> 4)) as u64)));
|
|
133
|
+
vector::push_back(&mut res, *vector::borrow(&TABLE, (((*vector::borrow(str, m + 1) & 0x0f) << 2) as u64)));
|
|
134
|
+
vector::push_back(&mut res, eq);
|
|
135
|
+
}else {
|
|
136
|
+
vector::push_back(&mut res, *vector::borrow(&TABLE, ((((*vector::borrow(str, m) & 0x03) << 4) + ((*vector::borrow(str, m + 1) & 0xf0) >> 4)) as u64)));
|
|
137
|
+
vector::push_back(&mut res, *vector::borrow(&TABLE, ((((*vector::borrow(str, m + 1) & 0x0f) << 2) + ((*vector::borrow(str, m + 2) & 0xc0) >> 6)) as u64)));
|
|
138
|
+
vector::push_back(&mut res, *vector::borrow(&TABLE, ((*vector::borrow(str, m + 2) & 0x3f) as u64)));
|
|
139
|
+
};
|
|
140
|
+
}else {
|
|
141
|
+
vector::push_back(&mut res, *vector::borrow(&TABLE, ((((*vector::borrow(str, m) & 0x03) << 4) + ((*vector::borrow(str, m + 1) & 0xf0) >> 4)) as u64)));
|
|
142
|
+
vector::push_back(&mut res, *vector::borrow(&TABLE, ((((*vector::borrow(str, m + 1) & 0x0f) << 2) + ((*vector::borrow(str, m + 2) & 0xc0) >> 6)) as u64)));
|
|
143
|
+
vector::push_back(&mut res, *vector::borrow(&TABLE, ((*vector::borrow(str, m + 2) & 0x3f) as u64)));
|
|
144
|
+
};
|
|
145
|
+
m = m + 3;
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
return res
|
|
149
|
+
}
|
|
150
|
+
}
|