cbor.odin 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674
  1. package encoding_cbor
  2. import "base:intrinsics"
  3. import "core:encoding/json"
  4. import "core:encoding/hex"
  5. import "core:io"
  6. import "core:mem"
  7. import "core:strconv"
  8. import "core:strings"
  9. // If we are decoding a stream of either a map or list, the initial capacity will be this value.
  10. INITIAL_STREAMED_CONTAINER_CAPACITY :: 8
  11. // If we are decoding a stream of either text or bytes, the initial capacity will be this value.
  12. INITIAL_STREAMED_BYTES_CAPACITY :: 16
  13. // The default maximum amount of bytes to allocate on a buffer/container at once to prevent
  14. // malicious input from causing massive allocations.
  15. DEFAULT_MAX_PRE_ALLOC :: mem.Kilobyte
  16. // Known/common headers are defined, undefined headers can still be valid.
  17. // Higher 3 bits is for the major type and lower 5 bits for the additional information.
  18. Header :: enum u8 {
  19. U8 = (u8(Major.Unsigned) << 5) | u8(Add.One_Byte),
  20. U16 = (u8(Major.Unsigned) << 5) | u8(Add.Two_Bytes),
  21. U32 = (u8(Major.Unsigned) << 5) | u8(Add.Four_Bytes),
  22. U64 = (u8(Major.Unsigned) << 5) | u8(Add.Eight_Bytes),
  23. Neg_U8 = (u8(Major.Negative) << 5) | u8(Add.One_Byte),
  24. Neg_U16 = (u8(Major.Negative) << 5) | u8(Add.Two_Bytes),
  25. Neg_U32 = (u8(Major.Negative) << 5) | u8(Add.Four_Bytes),
  26. Neg_U64 = (u8(Major.Negative) << 5) | u8(Add.Eight_Bytes),
  27. False = (u8(Major.Other) << 5) | u8(Add.False),
  28. True = (u8(Major.Other) << 5) | u8(Add.True),
  29. Nil = (u8(Major.Other) << 5) | u8(Add.Nil),
  30. Undefined = (u8(Major.Other) << 5) | u8(Add.Undefined),
  31. Simple = (u8(Major.Other) << 5) | u8(Add.One_Byte),
  32. F16 = (u8(Major.Other) << 5) | u8(Add.Two_Bytes),
  33. F32 = (u8(Major.Other) << 5) | u8(Add.Four_Bytes),
  34. F64 = (u8(Major.Other) << 5) | u8(Add.Eight_Bytes),
  35. Break = (u8(Major.Other) << 5) | u8(Add.Break),
  36. }
  37. // The higher 3 bits of the header which denotes what type of value it is.
  38. Major :: enum u8 {
  39. Unsigned,
  40. Negative,
  41. Bytes,
  42. Text,
  43. Array,
  44. Map,
  45. Tag,
  46. Other,
  47. }
  48. // The lower 3 bits of the header which denotes additional information for the type of value.
  49. Add :: enum u8 {
  50. False = 20,
  51. True = 21,
  52. Nil = 22,
  53. Undefined = 23,
  54. One_Byte = 24,
  55. Two_Bytes = 25,
  56. Four_Bytes = 26,
  57. Eight_Bytes = 27,
  58. Length_Unknown = 31,
  59. Break = Length_Unknown,
  60. }
  61. Value :: union {
  62. u8,
  63. u16,
  64. u32,
  65. u64,
  66. Negative_U8,
  67. Negative_U16,
  68. Negative_U32,
  69. Negative_U64,
  70. // Pointers so the size of the Value union stays small.
  71. ^Bytes,
  72. ^Text,
  73. ^Array,
  74. ^Map,
  75. ^Tag,
  76. Simple,
  77. f16,
  78. f32,
  79. f64,
  80. bool,
  81. Undefined,
  82. Nil,
  83. }
  84. Bytes :: []byte
  85. Text :: string
  86. Array :: []Value
  87. Map :: []Map_Entry
  88. Map_Entry :: struct {
  89. key: Value, // Can be any unsigned, negative, float, Simple, bool, Text.
  90. value: Value,
  91. }
  92. Tag :: struct {
  93. number: Tag_Number,
  94. value: Value, // Value based on the number.
  95. }
  96. Tag_Number :: u64
  97. Nil :: distinct rawptr
  98. Undefined :: distinct rawptr
  99. // A distinct atom-like number, range from `0..=19` and `32..=max(u8)`.
  100. Simple :: distinct u8
  101. Atom :: Simple
  102. Unmarshal_Error :: union #shared_nil {
  103. io.Error,
  104. mem.Allocator_Error,
  105. Decode_Data_Error,
  106. Unmarshal_Data_Error,
  107. Maybe(Unsupported_Type_Error),
  108. }
  109. Marshal_Error :: union #shared_nil {
  110. io.Error,
  111. mem.Allocator_Error,
  112. Encode_Data_Error,
  113. Marshal_Data_Error,
  114. Maybe(Unsupported_Type_Error),
  115. }
  116. Decode_Error :: union #shared_nil {
  117. io.Error,
  118. mem.Allocator_Error,
  119. Decode_Data_Error,
  120. }
  121. Encode_Error :: union #shared_nil {
  122. io.Error,
  123. mem.Allocator_Error,
  124. Encode_Data_Error,
  125. }
  126. Decode_Data_Error :: enum {
  127. None,
  128. Bad_Major, // An invalid major type was encountered.
  129. Bad_Argument, // A general unexpected value (most likely invalid additional info in header).
  130. Bad_Tag_Value, // When the type of value for the given tag is not valid.
  131. Nested_Indefinite_Length, // When an streamed/indefinite length container nests another, this is not allowed.
  132. Nested_Tag, // When a tag's value is another tag, this is not allowed.
  133. Length_Too_Big, // When the length of a container (map, array, bytes, string) is more than `max(int)`.
  134. Disallowed_Streaming, // When the `.Disallow_Streaming` flag is set and a streaming header is encountered.
  135. Break, // When the `break` header was found without any stream to break off.
  136. }
  137. Encode_Data_Error :: enum {
  138. None,
  139. Invalid_Simple, // When a simple is being encoded that is out of the range `0..=19` and `32..=max(u8)`.
  140. Int_Too_Big, // When an int is being encoded that is larger than `max(u64)` or smaller than `min(u64)`.
  141. Bad_Tag_Value, // When the type of value is not supported by the tag implementation.
  142. }
  143. Unmarshal_Data_Error :: enum {
  144. None,
  145. Invalid_Parameter, // When the given `any` can not be unmarshalled into.
  146. Non_Pointer_Parameter, // When the given `any` is not a pointer.
  147. }
  148. Marshal_Data_Error :: enum {
  149. None,
  150. Invalid_CBOR_Tag, // When the struct tag `cbor_tag:""` is not a registered name or number.
  151. }
  152. // Error that is returned when a type couldn't be marshalled into or out of, as much information
  153. // as possible/available is added.
  154. Unsupported_Type_Error :: struct {
  155. id: typeid,
  156. hdr: Header,
  157. add: Add,
  158. }
  159. _unsupported :: proc(v: any, hdr: Header, add: Add = nil) -> Maybe(Unsupported_Type_Error) {
  160. return Unsupported_Type_Error{
  161. id = v.id,
  162. hdr = hdr,
  163. add = add,
  164. }
  165. }
  166. // Actual value is `-1 - x` (be careful of overflows).
  167. Negative_U8 :: distinct u8
  168. Negative_U16 :: distinct u16
  169. Negative_U32 :: distinct u32
  170. Negative_U64 :: distinct u64
  171. // Turns the CBOR negative unsigned int type into a signed integer type.
  172. negative_to_int :: proc {
  173. negative_u8_to_int,
  174. negative_u16_to_int,
  175. negative_u32_to_int,
  176. negative_u64_to_int,
  177. }
  178. negative_u8_to_int :: #force_inline proc(u: Negative_U8) -> i16 {
  179. return -1 - i16(u)
  180. }
  181. negative_u16_to_int :: #force_inline proc(u: Negative_U16) -> i32 {
  182. return -1 - i32(u)
  183. }
  184. negative_u32_to_int :: #force_inline proc(u: Negative_U32) -> i64 {
  185. return -1 - i64(u)
  186. }
  187. negative_u64_to_int :: #force_inline proc(u: Negative_U64) -> i128 {
  188. return -1 - i128(u)
  189. }
  190. // Utility for converting between the different errors when they are subsets of the other.
  191. err_conv :: proc {
  192. encode_to_marshal_err,
  193. encode_to_marshal_err_p2,
  194. decode_to_unmarshal_err,
  195. decode_to_unmarshal_err_p,
  196. decode_to_unmarshal_err_p2,
  197. }
  198. encode_to_marshal_err :: #force_inline proc(err: Encode_Error) -> Marshal_Error {
  199. switch e in err {
  200. case nil: return nil
  201. case io.Error: return e
  202. case mem.Allocator_Error: return e
  203. case Encode_Data_Error: return e
  204. case: return nil
  205. }
  206. }
  207. encode_to_marshal_err_p2 :: #force_inline proc(v: $T, v2: $T2, err: Encode_Error) -> (T, T2, Marshal_Error) {
  208. return v, v2, err_conv(err)
  209. }
  210. decode_to_unmarshal_err :: #force_inline proc(err: Decode_Error) -> Unmarshal_Error {
  211. switch e in err {
  212. case nil: return nil
  213. case io.Error: return e
  214. case mem.Allocator_Error: return e
  215. case Decode_Data_Error: return e
  216. case: return nil
  217. }
  218. }
  219. decode_to_unmarshal_err_p :: #force_inline proc(v: $T, err: Decode_Error) -> (T, Unmarshal_Error) {
  220. return v, err_conv(err)
  221. }
  222. decode_to_unmarshal_err_p2 :: #force_inline proc(v: $T, v2: $T2, err: Decode_Error) -> (T, T2, Unmarshal_Error) {
  223. return v, v2, err_conv(err)
  224. }
  225. // Recursively frees all memory allocated when decoding the passed value.
  226. destroy :: proc(val: Value, allocator := context.allocator) {
  227. context.allocator = allocator
  228. #partial switch v in val {
  229. case ^Map:
  230. if v == nil { return }
  231. for entry in v {
  232. destroy(entry.key)
  233. destroy(entry.value)
  234. }
  235. delete(v^)
  236. free(v)
  237. case ^Array:
  238. if v == nil { return }
  239. for entry in v {
  240. destroy(entry)
  241. }
  242. delete(v^)
  243. free(v)
  244. case ^Text:
  245. if v == nil { return }
  246. delete(v^)
  247. free(v)
  248. case ^Bytes:
  249. if v == nil { return }
  250. delete(v^)
  251. free(v)
  252. case ^Tag:
  253. if v == nil { return }
  254. destroy(v.value)
  255. free(v)
  256. }
  257. }
  258. /*
  259. to_diagnostic_format either writes or returns a human-readable representation of the value,
  260. optionally formatted, defined as the diagnostic format in [[RFC 8949 Section 8;https://www.rfc-editor.org/rfc/rfc8949.html#name-diagnostic-notation]].
  261. Incidentally, if the CBOR does not contain any of the additional types defined on top of JSON
  262. this will also be valid JSON.
  263. */
  264. to_diagnostic_format :: proc {
  265. to_diagnostic_format_string,
  266. to_diagnostic_format_writer,
  267. }
  268. // Turns the given CBOR value into a human-readable string.
  269. // See docs on the proc group `diagnose` for more info.
  270. to_diagnostic_format_string :: proc(val: Value, padding := 0, allocator := context.allocator, loc := #caller_location) -> (string, mem.Allocator_Error) #optional_allocator_error {
  271. b := strings.builder_make(allocator, loc)
  272. w := strings.to_stream(&b)
  273. err := to_diagnostic_format_writer(w, val, padding)
  274. if err == .EOF {
  275. // The string builder stream only returns .EOF, and only if it can't write (out of memory).
  276. return "", .Out_Of_Memory
  277. }
  278. assert(err == nil)
  279. return strings.to_string(b), nil
  280. }
  281. // Writes the given CBOR value into the writer as human-readable text.
  282. // See docs on the proc group `diagnose` for more info.
  283. to_diagnostic_format_writer :: proc(w: io.Writer, val: Value, padding := 0) -> io.Error {
  284. @(require_results)
  285. indent :: proc(padding: int) -> int {
  286. padding := padding
  287. if padding != -1 {
  288. padding += 1
  289. }
  290. return padding
  291. }
  292. @(require_results)
  293. dedent :: proc(padding: int) -> int {
  294. padding := padding
  295. if padding != -1 {
  296. padding -= 1
  297. }
  298. return padding
  299. }
  300. comma :: proc(w: io.Writer, padding: int) -> io.Error {
  301. _ = io.write_string(w, ", " if padding == -1 else ",") or_return
  302. return nil
  303. }
  304. newline :: proc(w: io.Writer, padding: int) -> io.Error {
  305. if padding != -1 {
  306. io.write_string(w, "\n") or_return
  307. for _ in 0..<padding {
  308. io.write_string(w, "\t") or_return
  309. }
  310. }
  311. return nil
  312. }
  313. padding := padding
  314. switch v in val {
  315. case u8: io.write_uint(w, uint(v)) or_return
  316. case u16: io.write_uint(w, uint(v)) or_return
  317. case u32: io.write_uint(w, uint(v)) or_return
  318. case u64: io.write_u64(w, v) or_return
  319. case Negative_U8: io.write_int(w, int(negative_to_int(v))) or_return
  320. case Negative_U16: io.write_int(w, int(negative_to_int(v))) or_return
  321. case Negative_U32: io.write_int(w, int(negative_to_int(v))) or_return
  322. case Negative_U64: io.write_i128(w, i128(negative_to_int(v))) or_return
  323. // NOTE: not using io.write_float because it removes the sign,
  324. // which we want for the diagnostic format.
  325. case f16:
  326. buf: [64]byte
  327. str := strconv.append_float(buf[:], f64(v), 'f', 2*size_of(f16), 8*size_of(f16))
  328. if str[0] == '+' && str != "+Inf" { str = str[1:] }
  329. io.write_string(w, str) or_return
  330. case f32:
  331. buf: [128]byte
  332. str := strconv.append_float(buf[:], f64(v), 'f', 2*size_of(f32), 8*size_of(f32))
  333. if str[0] == '+' && str != "+Inf" { str = str[1:] }
  334. io.write_string(w, str) or_return
  335. case f64:
  336. buf: [256]byte
  337. str := strconv.append_float(buf[:], f64(v), 'f', 2*size_of(f64), 8*size_of(f64))
  338. if str[0] == '+' && str != "+Inf" { str = str[1:] }
  339. io.write_string(w, str) or_return
  340. case bool: io.write_string(w, "true" if v else "false") or_return
  341. case Nil: io.write_string(w, "null") or_return
  342. case Undefined: io.write_string(w, "undefined") or_return
  343. case ^Bytes:
  344. io.write_string(w, "h'") or_return
  345. hex.encode_into_writer(w, v^) or_return
  346. io.write_string(w, "'") or_return
  347. case ^Text:
  348. io.write_string(w, `"`) or_return
  349. io.write_string(w, v^) or_return
  350. io.write_string(w, `"`) or_return
  351. case ^Array:
  352. if v == nil || len(v) == 0 {
  353. io.write_string(w, "[]") or_return
  354. return nil
  355. }
  356. io.write_string(w, "[") or_return
  357. padding = indent(padding)
  358. newline(w, padding) or_return
  359. for entry, i in v {
  360. to_diagnostic_format(w, entry, padding) or_return
  361. if i != len(v)-1 {
  362. comma(w, padding) or_return
  363. newline(w, padding) or_return
  364. }
  365. }
  366. padding = dedent(padding)
  367. newline(w, padding) or_return
  368. io.write_string(w, "]") or_return
  369. case ^Map:
  370. if v == nil || len(v) == 0 {
  371. io.write_string(w, "{}") or_return
  372. return nil
  373. }
  374. io.write_string(w, "{") or_return
  375. padding = indent(padding)
  376. newline(w, padding) or_return
  377. for entry, i in v {
  378. to_diagnostic_format(w, entry.key, padding) or_return
  379. io.write_string(w, ": ") or_return
  380. to_diagnostic_format(w, entry.value, padding) or_return
  381. if i != len(v)-1 {
  382. comma(w, padding) or_return
  383. newline(w, padding) or_return
  384. }
  385. }
  386. padding = dedent(padding)
  387. newline(w, padding) or_return
  388. io.write_string(w, "}") or_return
  389. case ^Tag:
  390. io.write_u64(w, v.number) or_return
  391. io.write_string(w, "(") or_return
  392. to_diagnostic_format(w, v.value, padding) or_return
  393. io.write_string(w, ")") or_return
  394. case Simple:
  395. io.write_string(w, "simple(") or_return
  396. io.write_uint(w, uint(v)) or_return
  397. io.write_string(w, ")") or_return
  398. }
  399. return nil
  400. }
  401. /*
  402. Converts from JSON to CBOR.
  403. Everything is copied to the given allocator, the passed in JSON value can be deleted after.
  404. */
  405. from_json :: proc(val: json.Value, allocator := context.allocator) -> (Value, mem.Allocator_Error) #optional_allocator_error {
  406. internal :: proc(val: json.Value) -> (ret: Value, err: mem.Allocator_Error) {
  407. switch v in val {
  408. case json.Null: return Nil{}, nil
  409. case json.Integer:
  410. i, major := _int_to_uint(v)
  411. #partial switch major {
  412. case .Unsigned: return i, nil
  413. case .Negative: return Negative_U64(i), nil
  414. case: unreachable()
  415. }
  416. case json.Float: return v, nil
  417. case json.Boolean: return v, nil
  418. case json.String:
  419. container := new(Text) or_return
  420. // We need the string to have a nil byte at the end so we clone to cstring.
  421. container^ = string(strings.clone_to_cstring(v) or_return)
  422. return container, nil
  423. case json.Array:
  424. arr := new(Array) or_return
  425. arr^ = make([]Value, len(v)) or_return
  426. for _, i in arr {
  427. arr[i] = internal(v[i]) or_return
  428. }
  429. return arr, nil
  430. case json.Object:
  431. m := new(Map) or_return
  432. dm := make([dynamic]Map_Entry, 0, len(v)) or_return
  433. for mkey, mval in v {
  434. append(&dm, Map_Entry{from_json(mkey) or_return, from_json(mval) or_return})
  435. }
  436. m^ = dm[:]
  437. return m, nil
  438. }
  439. return nil, nil
  440. }
  441. context.allocator = allocator
  442. return internal(val)
  443. }
  444. /*
  445. Converts from CBOR to JSON.
  446. NOTE: overflow on integers or floats is not handled.
  447. Everything is copied to the given allocator, the passed in CBOR value can be `destroy`'ed after.
  448. If a CBOR map with non-string keys is encountered it is turned into an array of tuples.
  449. */
  450. to_json :: proc(val: Value, allocator := context.allocator) -> (json.Value, mem.Allocator_Error) #optional_allocator_error {
  451. internal :: proc(val: Value) -> (ret: json.Value, err: mem.Allocator_Error) {
  452. switch v in val {
  453. case Simple: return json.Integer(v), nil
  454. case u8: return json.Integer(v), nil
  455. case u16: return json.Integer(v), nil
  456. case u32: return json.Integer(v), nil
  457. case u64: return json.Integer(v), nil
  458. case Negative_U8: return json.Integer(negative_to_int(v)), nil
  459. case Negative_U16: return json.Integer(negative_to_int(v)), nil
  460. case Negative_U32: return json.Integer(negative_to_int(v)), nil
  461. case Negative_U64: return json.Integer(negative_to_int(v)), nil
  462. case f16: return json.Float(v), nil
  463. case f32: return json.Float(v), nil
  464. case f64: return json.Float(v), nil
  465. case bool: return json.Boolean(v), nil
  466. case Undefined: return json.Null{}, nil
  467. case Nil: return json.Null{}, nil
  468. case ^Bytes: return json.String(strings.clone(string(v^)) or_return), nil
  469. case ^Text: return json.String(strings.clone(v^) or_return), nil
  470. case ^Map:
  471. keys_all_strings :: proc(m: ^Map) -> bool {
  472. for entry in m {
  473. #partial switch kv in entry.key {
  474. case ^Bytes:
  475. case ^Text:
  476. case: return false
  477. }
  478. }
  479. return true
  480. }
  481. if keys_all_strings(v) {
  482. obj := make(json.Object, len(v)) or_return
  483. for entry in v {
  484. k: string
  485. #partial switch kv in entry.key {
  486. case ^Bytes: k = string(kv^)
  487. case ^Text: k = kv^
  488. case: unreachable()
  489. }
  490. v := internal(entry.value) or_return
  491. obj[k] = v
  492. }
  493. return obj, nil
  494. } else {
  495. // Resort to an array of tuples if keys aren't all strings.
  496. arr := make(json.Array, 0, len(v)) or_return
  497. for entry in v {
  498. entry_arr := make(json.Array, 0, 2) or_return
  499. append(&entry_arr, internal(entry.key) or_return) or_return
  500. append(&entry_arr, internal(entry.value) or_return) or_return
  501. append(&arr, entry_arr) or_return
  502. }
  503. return arr, nil
  504. }
  505. case ^Array:
  506. arr := make(json.Array, 0, len(v)) or_return
  507. for entry in v {
  508. append(&arr, internal(entry) or_return) or_return
  509. }
  510. return arr, nil
  511. case ^Tag:
  512. obj := make(json.Object, 2) or_return
  513. obj[strings.clone("number") or_return] = internal(v.number) or_return
  514. obj[strings.clone("value") or_return] = internal(v.value) or_return
  515. return obj, nil
  516. case: return json.Null{}, nil
  517. }
  518. }
  519. context.allocator = allocator
  520. return internal(val)
  521. }
  522. _int_to_uint :: proc {
  523. _i8_to_uint,
  524. _i16_to_uint,
  525. _i32_to_uint,
  526. _i64_to_uint,
  527. _i128_to_uint,
  528. }
  529. _u128_to_u64 :: #force_inline proc(v: u128) -> (u64, Encode_Data_Error) {
  530. if v > u128(max(u64)) {
  531. return 0, .Int_Too_Big
  532. }
  533. return u64(v), nil
  534. }
  535. _i8_to_uint :: #force_inline proc(v: i8) -> (u: u8, m: Major) {
  536. if v < 0 {
  537. return u8(abs(v)-1), .Negative
  538. }
  539. return u8(v), .Unsigned
  540. }
  541. _i16_to_uint :: #force_inline proc(v: i16) -> (u: u16, m: Major) {
  542. if v < 0 {
  543. return u16(abs(v)-1), .Negative
  544. }
  545. return u16(v), .Unsigned
  546. }
  547. _i32_to_uint :: #force_inline proc(v: i32) -> (u: u32, m: Major) {
  548. if v < 0 {
  549. return u32(abs(v)-1), .Negative
  550. }
  551. return u32(v), .Unsigned
  552. }
  553. _i64_to_uint :: #force_inline proc(v: i64) -> (u: u64, m: Major) {
  554. if v < 0 {
  555. return u64(abs(v)-1), .Negative
  556. }
  557. return u64(v), .Unsigned
  558. }
  559. _i128_to_uint :: proc(v: i128) -> (u: u64, m: Major, err: Encode_Data_Error) {
  560. if v < 0 {
  561. m = .Negative
  562. u, err = _u128_to_u64(u128(abs(v) - 1))
  563. return
  564. }
  565. m = .Unsigned
  566. u, err = _u128_to_u64(u128(v))
  567. return
  568. }