commit b7a022cceace51276affda54027fc15b9c4cfd0b Author: divo <418@cryspace.space> Date: Thu Sep 25 14:42:12 2025 -0400 init commit Signed-off-by: divo <418@cryspace.space> diff --git a/.dat/content.bitfield b/.dat/content.bitfield new file mode 100644 index 0000000..139afb5 Binary files /dev/null and b/.dat/content.bitfield differ diff --git a/.dat/content.key b/.dat/content.key new file mode 100644 index 0000000..6d18b85 Binary files /dev/null and b/.dat/content.key differ diff --git a/.dat/content.signatures b/.dat/content.signatures new file mode 100644 index 0000000..8eaa03e Binary files /dev/null and b/.dat/content.signatures differ diff --git a/.dat/content.tree b/.dat/content.tree new file mode 100644 index 0000000..4a56079 Binary files /dev/null and b/.dat/content.tree differ diff --git a/.dat/metadata.bitfield b/.dat/metadata.bitfield new file mode 100644 index 0000000..130dd46 Binary files /dev/null and b/.dat/metadata.bitfield differ diff --git a/.dat/metadata.data b/.dat/metadata.data new file mode 100644 index 0000000..d78d56b Binary files /dev/null and b/.dat/metadata.data differ diff --git a/.dat/metadata.key b/.dat/metadata.key new file mode 100644 index 0000000..2aea5d8 --- /dev/null +++ b/.dat/metadata.key @@ -0,0 +1 @@ +Y Q#ƓXXoAXrb*  \ No newline at end of file diff --git a/.dat/metadata.ogd b/.dat/metadata.ogd new file mode 100644 index 0000000..f76dd23 Binary files /dev/null and b/.dat/metadata.ogd differ diff --git a/.dat/metadata.signatures b/.dat/metadata.signatures new file mode 100644 index 0000000..4a0c9b9 Binary files /dev/null and b/.dat/metadata.signatures differ diff --git a/.dat/metadata.tree b/.dat/metadata.tree new file mode 100644 index 0000000..dd4e1e0 Binary files /dev/null and b/.dat/metadata.tree differ diff --git a/dat.json b/dat.json new file mode 100644 index 0000000..8922088 --- /dev/null +++ b/dat.json @@ -0,0 +1,5 @@ +{ + "title": "dat-thang", + "description": "dat:// implemented over c & scheme", + "url": "dat://59d8099399510e23a3c693fb5887b7bba1586f4117f7ef1c5872622ada0c1181" +} \ No newline at end of file diff --git a/docs/dat-paper.pdf b/docs/dat-paper.pdf new file mode 100644 index 0000000..500427e Binary files /dev/null and b/docs/dat-paper.pdf differ diff --git a/docs/sleep.pdf b/docs/sleep.pdf new file mode 100644 index 0000000..1c59c91 Binary files /dev/null and b/docs/sleep.pdf differ diff --git a/extra/parse.js b/extra/parse.js new file mode 100644 index 0000000..4f8689b --- /dev/null +++ b/extra/parse.js @@ -0,0 +1,29 @@ +const isNode = typeof window === 'undefined' +const parse = isNode ? require('url').parse : browserParse + +const SCHEME_REGEX = /[a-z]+:\/\//i +// 1 2 3 4 +const VERSION_REGEX = /^(dat:\/\/)?([^/]+)(\+[^/]+)(.*)$/i + +module.exports = function parseDatURL (str, parseQS) { + // prepend the scheme if it's missing + if (!SCHEME_REGEX.test(str)) { + str = 'dat://' + str + } + + var parsed, version = null, match = VERSION_REGEX.exec(str) + if (match) { + // run typical parse with version segment removed + parsed = parse((match[1] || '') + (match[2] || '') + (match[4] || ''), parseQS) + version = match[3].slice(1) + } else { + parsed = parse(str, parseQS) + } + if (isNode) parsed.href = str // overwrite href to include actual original + parsed.version = version // add version segment + return parsed +} + +function browserParse (str) { + return new URL(str) +} \ No newline at end of file diff --git a/schema.proto b/schema.proto new file mode 100644 index 0000000..92db6c1 --- /dev/null +++ b/schema.proto @@ -0,0 +1,82 @@ +// wire format is (
) +// header is a varint, channel << 4 | <4-bit-type> + +// type=0, should be the first message sent on a channel +message Feed { + required bytes discoveryKey = 1; + optional bytes nonce = 2; +} + +// type=1, overall connection handshake. should be send just after the feed message on the first channel only +message Handshake { + optional bytes id = 1; + optional bool live = 2; // keep the connection open forever? both ends have to agree + optional bytes userData = 3; + repeated string extensions = 4; + optional bool ack = 5; // Should all blocks be explicitly acknowledged? +} + +// type=2, message indicating state changes etc. +// initial state for uploading/downloading is true +// if both ends are not downloading and not live it is safe to consider the stream ended +message Info { + optional bool uploading = 1; + optional bool downloading = 2; +} + +// type=3, what do we have? +message Have { + required uint64 start = 1; + optional uint64 length = 2 [default = 1]; // defaults to 1 + optional bytes bitfield = 3; +} + +// type=4, what did we lose? +message Unhave { + required uint64 start = 1; + optional uint64 length = 2 [default = 1]; // defaults to 1 +} + +// type=5, what do we want? remote should start sending have messages in this range +message Want { + required uint64 start = 1; + optional uint64 length = 2; // defaults to Infinity or feed.length (if not live) +} + +// type=6, what don't we want anymore? +message Unwant { + required uint64 start = 1; + optional uint64 length = 2; // defaults to Infinity or feed.length (if not live) +} + +// type=7, ask for data +message Request { + required uint64 index = 1; + optional uint64 bytes = 2; + optional bool hash = 3; + optional uint64 nodes = 4; +} + +// type=8, cancel a request +message Cancel { + required uint64 index = 1; + optional uint64 bytes = 2; + optional bool hash = 3; +} + +// type=9, get some data +message Data { + message Node { + required uint64 index = 1; + required bytes hash = 2; + required uint64 size = 3; + } + + required uint64 index = 1; + optional bytes value = 2; + repeated Node nodes = 3; + optional bytes signature = 4; +} + +// type=15 (last message) is an extension message +// that is encoded like this \ No newline at end of file diff --git a/varint.scm b/varint.scm new file mode 100644 index 0000000..28c0e99 --- /dev/null +++ b/varint.scm @@ -0,0 +1,40 @@ +;; VarInt encoding and decoding utilities +;; These functions implement variable-length integer encoding commonly used in Protocol Buffers + +;; Encode a positive integer into a varint format +(define (encode-varint n) + (cond ((< n 128) + ;; Single byte case + (list n)) + (else + ;; Recursive case: encode remaining bits and prepend current byte + (append (encode-varint (arithmetic-shift n -7)) + (list (bitwise-or (logand n 127) 128)))))) + +;; Decode a varint from a sequence of bytes +(define (decode-varint bytes) + (define (decode-helper bytes result shift) + (if (null? bytes) + (error "Incomplete varint")) + (let ((byte (car bytes))) + (cond ((zero? (bitwise-and byte 128)) + ;; Last byte encountered + (+ result (arithmetic-shift byte shift))) + (else + ;; Continue decoding with next byte + (decode-helper (cdr bytes) + (+ result (arithmetic-shift (logand byte 127) shift)) + (+ shift 7))))))) + (decode-helper bytes 0)) + +;; Helper functions for working with varints +(define (varint-bytes->list bytes) + (map (lambda (byte) (if (integer? byte) byte (char->integer byte))) bytes)) + +(define (varint-list->bytes encoded) + (map char encoded)) +;; Example usage +(let ((encoded (encode-varint 16384))) + (display "Encoded varint: ") (write encoded) (newline) + (let ((decoded (decode-varint encoded))) + (display "Decoded value: ") (display decoded) (newline))) \ No newline at end of file