1// Copyright 2014 The lldb Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5// Utilities to encode/decode and collate Go predeclared scalar types (and the 6// typeless nil and []byte). The encoding format is a variation of the one 7// used by the "encoding/gob" package. 8 9package lldb 10 11import ( 12 "bytes" 13 "fmt" 14 "math" 15 16 "github.com/cznic/mathutil" 17) 18 19const ( 20 gbNull = iota // 0x00 21 gbFalse // 0x01 22 gbTrue // 0x02 23 gbFloat0 // 0x03 24 gbFloat1 // 0x04 25 gbFloat2 // 0x05 26 gbFloat3 // 0x06 27 gbFloat4 // 0x07 28 gbFloat5 // 0x08 29 gbFloat6 // 0x09 30 gbFloat7 // 0x0a 31 gbFloat8 // 0x0b 32 gbComplex0 // 0x0c 33 gbComplex1 // 0x0d 34 gbComplex2 // 0x0e 35 gbComplex3 // 0x0f 36 gbComplex4 // 0x10 37 gbComplex5 // 0x11 38 gbComplex6 // 0x12 39 gbComplex7 // 0x13 40 gbComplex8 // 0x14 41 gbBytes00 // 0x15 42 gbBytes01 // 0x16 43 gbBytes02 // 0x17 44 gbBytes03 // 0x18 45 gbBytes04 // 0x19 46 gbBytes05 // 0x1a 47 gbBytes06 // 0x1b 48 gbBytes07 // 0x1c 49 gbBytes08 // 0x1d 50 gbBytes09 // 0x1e 51 gbBytes10 // 0x1f 52 gbBytes11 // 0x20 53 gbBytes12 // 0x21 54 gbBytes13 // 0x22 55 gbBytes14 // 0x23 56 gbBytes15 // 0x24 57 gbBytes16 // 0x25 58 gbBytes17 // Ox26 59 gbBytes1 // 0x27 60 gbBytes2 // 0x28: Offset by one to allow 64kB sized []byte. 61 gbString00 // 0x29 62 gbString01 // 0x2a 63 gbString02 // 0x2b 64 gbString03 // 0x2c 65 gbString04 // 0x2d 66 gbString05 // 0x2e 67 gbString06 // 0x2f 68 gbString07 // 0x30 69 gbString08 // 0x31 70 gbString09 // 0x32 71 gbString10 // 0x33 72 gbString11 // 0x34 73 gbString12 // 0x35 74 gbString13 // 0x36 75 gbString14 // 0x37 76 gbString15 // 0x38 77 gbString16 // 0x39 78 gbString17 // 0x3a 79 gbString1 // 0x3b 80 gbString2 // 0x3c 81 gbUintP1 // 0x3d 82 gbUintP2 // 0x3e 83 gbUintP3 // 0x3f 84 gbUintP4 // 0x40 85 gbUintP5 // 0x41 86 gbUintP6 // 0x42 87 gbUintP7 // 0x43 88 gbUintP8 // 0x44 89 gbIntM8 // 0x45 90 gbIntM7 // 0x46 91 gbIntM6 // 0x47 92 gbIntM5 // 0x48 93 gbIntM4 // 0x49 94 gbIntM3 // 0x4a 95 gbIntM2 // 0x4b 96 gbIntM1 // 0x4c 97 gbIntP1 // 0x4d 98 gbIntP2 // 0x4e 99 gbIntP3 // 0x4f 100 gbIntP4 // 0x50 101 gbIntP5 // 0x51 102 gbIntP6 // 0x52 103 gbIntP7 // 0x53 104 gbIntP8 // 0x54 105 gbInt0 // 0x55 106 107 gbIntMax = 255 - gbInt0 // 0xff == 170 108) 109 110// EncodeScalars encodes a vector of predeclared scalar type values to a 111// []byte, making it suitable to store it as a "record" in a DB or to use it as 112// a key of a BTree. 113func EncodeScalars(scalars ...interface{}) (b []byte, err error) { 114 for _, scalar := range scalars { 115 switch x := scalar.(type) { 116 default: 117 return nil, &ErrINVAL{"EncodeScalars: unsupported type", fmt.Sprintf("%T in `%#v`", x, scalars)} 118 119 case nil: 120 b = append(b, gbNull) 121 122 case bool: 123 switch x { 124 case false: 125 b = append(b, gbFalse) 126 case true: 127 b = append(b, gbTrue) 128 } 129 130 case float32: 131 encFloat(float64(x), &b) 132 case float64: 133 encFloat(x, &b) 134 135 case complex64: 136 encComplex(complex128(x), &b) 137 case complex128: 138 encComplex(x, &b) 139 140 case string: 141 n := len(x) 142 if n <= 17 { 143 b = append(b, byte(gbString00+n)) 144 b = append(b, []byte(x)...) 145 break 146 } 147 148 if n > 65535 { 149 return nil, fmt.Errorf("EncodeScalars: cannot encode string of length %d (limit 65536)", n) 150 } 151 152 pref := byte(gbString1) 153 if n > 255 { 154 pref++ 155 } 156 b = append(b, pref) 157 encUint0(uint64(n), &b) 158 b = append(b, []byte(x)...) 159 160 case int8: 161 encInt(int64(x), &b) 162 case int16: 163 encInt(int64(x), &b) 164 case int32: 165 encInt(int64(x), &b) 166 case int64: 167 encInt(x, &b) 168 case int: 169 encInt(int64(x), &b) 170 171 case uint8: 172 encUint(uint64(x), &b) 173 case uint16: 174 encUint(uint64(x), &b) 175 case uint32: 176 encUint(uint64(x), &b) 177 case uint64: 178 encUint(x, &b) 179 case uint: 180 encUint(uint64(x), &b) 181 case []byte: 182 n := len(x) 183 if n <= 17 { 184 b = append(b, byte(gbBytes00+n)) 185 b = append(b, x...) 186 break 187 } 188 189 if n > 655356 { 190 return nil, fmt.Errorf("EncodeScalars: cannot encode []byte of length %d (limit 65536)", n) 191 } 192 193 pref := byte(gbBytes1) 194 if n > 255 { 195 pref++ 196 } 197 b = append(b, pref) 198 if n <= 255 { 199 b = append(b, byte(n)) 200 } else { 201 n-- 202 b = append(b, byte(n>>8), byte(n)) 203 } 204 b = append(b, x...) 205 } 206 } 207 return 208} 209 210func encComplex(f complex128, b *[]byte) { 211 encFloatPrefix(gbComplex0, real(f), b) 212 encFloatPrefix(gbComplex0, imag(f), b) 213} 214 215func encFloatPrefix(prefix byte, f float64, b *[]byte) { 216 u := math.Float64bits(f) 217 var n uint64 218 for i := 0; i < 8; i++ { 219 n <<= 8 220 n |= u & 0xFF 221 u >>= 8 222 } 223 bits := mathutil.BitLenUint64(n) 224 if bits == 0 { 225 *b = append(*b, prefix) 226 return 227 } 228 229 // 0 1 2 3 4 5 6 7 8 9 230 // . 1 1 1 1 1 1 1 1 2 231 encUintPrefix(prefix+1+byte((bits-1)>>3), n, b) 232} 233 234func encFloat(f float64, b *[]byte) { 235 encFloatPrefix(gbFloat0, f, b) 236} 237 238func encUint0(n uint64, b *[]byte) { 239 switch { 240 case n <= 0xff: 241 *b = append(*b, byte(n)) 242 case n <= 0xffff: 243 *b = append(*b, byte(n>>8), byte(n)) 244 case n <= 0xffffff: 245 *b = append(*b, byte(n>>16), byte(n>>8), byte(n)) 246 case n <= 0xffffffff: 247 *b = append(*b, byte(n>>24), byte(n>>16), byte(n>>8), byte(n)) 248 case n <= 0xffffffffff: 249 *b = append(*b, byte(n>>32), byte(n>>24), byte(n>>16), byte(n>>8), byte(n)) 250 case n <= 0xffffffffffff: 251 *b = append(*b, byte(n>>40), byte(n>>32), byte(n>>24), byte(n>>16), byte(n>>8), byte(n)) 252 case n <= 0xffffffffffffff: 253 *b = append(*b, byte(n>>48), byte(n>>40), byte(n>>32), byte(n>>24), byte(n>>16), byte(n>>8), byte(n)) 254 case n <= math.MaxUint64: 255 *b = append(*b, byte(n>>56), byte(n>>48), byte(n>>40), byte(n>>32), byte(n>>24), byte(n>>16), byte(n>>8), byte(n)) 256 } 257} 258 259func encUintPrefix(prefix byte, n uint64, b *[]byte) { 260 *b = append(*b, prefix) 261 encUint0(n, b) 262} 263 264func encUint(n uint64, b *[]byte) { 265 bits := mathutil.Max(1, mathutil.BitLenUint64(n)) 266 encUintPrefix(gbUintP1+byte((bits-1)>>3), n, b) 267} 268 269func encInt(n int64, b *[]byte) { 270 switch { 271 case n < -0x100000000000000: 272 *b = append(*b, byte(gbIntM8), byte(n>>56), byte(n>>48), byte(n>>40), byte(n>>32), byte(n>>24), byte(n>>16), byte(n>>8), byte(n)) 273 case n < -0x1000000000000: 274 *b = append(*b, byte(gbIntM7), byte(n>>48), byte(n>>40), byte(n>>32), byte(n>>24), byte(n>>16), byte(n>>8), byte(n)) 275 case n < -0x10000000000: 276 *b = append(*b, byte(gbIntM6), byte(n>>40), byte(n>>32), byte(n>>24), byte(n>>16), byte(n>>8), byte(n)) 277 case n < -0x100000000: 278 *b = append(*b, byte(gbIntM5), byte(n>>32), byte(n>>24), byte(n>>16), byte(n>>8), byte(n)) 279 case n < -0x1000000: 280 *b = append(*b, byte(gbIntM4), byte(n>>24), byte(n>>16), byte(n>>8), byte(n)) 281 case n < -0x10000: 282 *b = append(*b, byte(gbIntM3), byte(n>>16), byte(n>>8), byte(n)) 283 case n < -0x100: 284 *b = append(*b, byte(gbIntM2), byte(n>>8), byte(n)) 285 case n < 0: 286 *b = append(*b, byte(gbIntM1), byte(n)) 287 case n <= gbIntMax: 288 *b = append(*b, byte(gbInt0+n)) 289 case n <= 0xff: 290 *b = append(*b, gbIntP1, byte(n)) 291 case n <= 0xffff: 292 *b = append(*b, gbIntP2, byte(n>>8), byte(n)) 293 case n <= 0xffffff: 294 *b = append(*b, gbIntP3, byte(n>>16), byte(n>>8), byte(n)) 295 case n <= 0xffffffff: 296 *b = append(*b, gbIntP4, byte(n>>24), byte(n>>16), byte(n>>8), byte(n)) 297 case n <= 0xffffffffff: 298 *b = append(*b, gbIntP5, byte(n>>32), byte(n>>24), byte(n>>16), byte(n>>8), byte(n)) 299 case n <= 0xffffffffffff: 300 *b = append(*b, gbIntP6, byte(n>>40), byte(n>>32), byte(n>>24), byte(n>>16), byte(n>>8), byte(n)) 301 case n <= 0xffffffffffffff: 302 *b = append(*b, gbIntP7, byte(n>>48), byte(n>>40), byte(n>>32), byte(n>>24), byte(n>>16), byte(n>>8), byte(n)) 303 case n <= 0x7fffffffffffffff: 304 *b = append(*b, gbIntP8, byte(n>>56), byte(n>>48), byte(n>>40), byte(n>>32), byte(n>>24), byte(n>>16), byte(n>>8), byte(n)) 305 } 306} 307 308func decodeFloat(b []byte) float64 { 309 var u uint64 310 for i, v := range b { 311 u |= uint64(v) << uint((i+8-len(b))*8) 312 } 313 return math.Float64frombits(u) 314} 315 316// DecodeScalars decodes a []byte produced by EncodeScalars. 317func DecodeScalars(b []byte) (scalars []interface{}, err error) { 318 b0 := b 319 for len(b) != 0 { 320 switch tag := b[0]; tag { 321 //default: 322 //return nil, fmt.Errorf("tag %d(%#x) not supported", b[0], b[0]) 323 case gbNull: 324 scalars = append(scalars, nil) 325 b = b[1:] 326 case gbFalse: 327 scalars = append(scalars, false) 328 b = b[1:] 329 case gbTrue: 330 scalars = append(scalars, true) 331 b = b[1:] 332 case gbFloat0: 333 scalars = append(scalars, 0.0) 334 b = b[1:] 335 case gbFloat1, gbFloat2, gbFloat3, gbFloat4, gbFloat5, gbFloat6, gbFloat7, gbFloat8: 336 n := 1 + int(tag) - gbFloat0 337 if len(b) < n-1 { 338 goto corrupted 339 } 340 341 scalars = append(scalars, decodeFloat(b[1:n])) 342 b = b[n:] 343 case gbComplex0, gbComplex1, gbComplex2, gbComplex3, gbComplex4, gbComplex5, gbComplex6, gbComplex7, gbComplex8: 344 n := 1 + int(tag) - gbComplex0 345 if len(b) < n-1 { 346 goto corrupted 347 } 348 349 re := decodeFloat(b[1:n]) 350 b = b[n:] 351 352 if len(b) == 0 { 353 goto corrupted 354 } 355 356 tag = b[0] 357 if tag < gbComplex0 || tag > gbComplex8 { 358 goto corrupted 359 } 360 361 n = 1 + int(tag) - gbComplex0 362 if len(b) < n-1 { 363 goto corrupted 364 } 365 366 scalars = append(scalars, complex(re, decodeFloat(b[1:n]))) 367 b = b[n:] 368 case gbBytes00, gbBytes01, gbBytes02, gbBytes03, gbBytes04, 369 gbBytes05, gbBytes06, gbBytes07, gbBytes08, gbBytes09, 370 gbBytes10, gbBytes11, gbBytes12, gbBytes13, gbBytes14, 371 gbBytes15, gbBytes16, gbBytes17: 372 n := int(tag - gbBytes00) 373 if len(b) < n+1 { 374 goto corrupted 375 } 376 377 scalars = append(scalars, append([]byte(nil), b[1:n+1]...)) 378 b = b[n+1:] 379 case gbBytes1: 380 if len(b) < 2 { 381 goto corrupted 382 } 383 384 n := int(b[1]) 385 b = b[2:] 386 if len(b) < n { 387 goto corrupted 388 } 389 390 scalars = append(scalars, append([]byte(nil), b[:n]...)) 391 b = b[n:] 392 case gbBytes2: 393 if len(b) < 3 { 394 goto corrupted 395 } 396 397 n := int(b[1])<<8 | int(b[2]) + 1 398 b = b[3:] 399 if len(b) < n { 400 goto corrupted 401 } 402 403 scalars = append(scalars, append([]byte(nil), b[:n]...)) 404 b = b[n:] 405 case gbString00, gbString01, gbString02, gbString03, gbString04, 406 gbString05, gbString06, gbString07, gbString08, gbString09, 407 gbString10, gbString11, gbString12, gbString13, gbString14, 408 gbString15, gbString16, gbString17: 409 n := int(tag - gbString00) 410 if len(b) < n+1 { 411 goto corrupted 412 } 413 414 scalars = append(scalars, string(b[1:n+1])) 415 b = b[n+1:] 416 case gbString1: 417 if len(b) < 2 { 418 goto corrupted 419 } 420 421 n := int(b[1]) 422 b = b[2:] 423 if len(b) < n { 424 goto corrupted 425 } 426 427 scalars = append(scalars, string(b[:n])) 428 b = b[n:] 429 case gbString2: 430 if len(b) < 3 { 431 goto corrupted 432 } 433 434 n := int(b[1])<<8 | int(b[2]) 435 b = b[3:] 436 if len(b) < n { 437 goto corrupted 438 } 439 440 scalars = append(scalars, string(b[:n])) 441 b = b[n:] 442 case gbUintP1, gbUintP2, gbUintP3, gbUintP4, gbUintP5, gbUintP6, gbUintP7, gbUintP8: 443 b = b[1:] 444 n := 1 + int(tag) - gbUintP1 445 if len(b) < n { 446 goto corrupted 447 } 448 449 var u uint64 450 for _, v := range b[:n] { 451 u = u<<8 | uint64(v) 452 } 453 scalars = append(scalars, u) 454 b = b[n:] 455 case gbIntM8, gbIntM7, gbIntM6, gbIntM5, gbIntM4, gbIntM3, gbIntM2, gbIntM1: 456 b = b[1:] 457 n := 8 - (int(tag) - gbIntM8) 458 if len(b) < n { 459 goto corrupted 460 } 461 u := uint64(math.MaxUint64) 462 for _, v := range b[:n] { 463 u = u<<8 | uint64(v) 464 } 465 scalars = append(scalars, int64(u)) 466 b = b[n:] 467 case gbIntP1, gbIntP2, gbIntP3, gbIntP4, gbIntP5, gbIntP6, gbIntP7, gbIntP8: 468 b = b[1:] 469 n := 1 + int(tag) - gbIntP1 470 if len(b) < n { 471 goto corrupted 472 } 473 474 i := int64(0) 475 for _, v := range b[:n] { 476 i = i<<8 | int64(v) 477 } 478 scalars = append(scalars, i) 479 b = b[n:] 480 default: 481 scalars = append(scalars, int64(b[0])-gbInt0) 482 b = b[1:] 483 } 484 } 485 return append([]interface{}(nil), scalars...), nil 486 487corrupted: 488 return nil, &ErrDecodeScalars{append([]byte(nil), b0...), len(b0) - len(b)} 489} 490 491func collateComplex(x, y complex128) int { 492 switch rx, ry := real(x), real(y); { 493 case rx < ry: 494 return -1 495 case rx == ry: 496 switch ix, iy := imag(x), imag(y); { 497 case ix < iy: 498 return -1 499 case ix == iy: 500 return 0 501 case ix > iy: 502 return 1 503 } 504 } 505 //case rx > ry: 506 return 1 507} 508 509func collateFloat(x, y float64) int { 510 switch { 511 case x < y: 512 return -1 513 case x == y: 514 return 0 515 } 516 //case x > y: 517 return 1 518} 519 520func collateInt(x, y int64) int { 521 switch { 522 case x < y: 523 return -1 524 case x == y: 525 return 0 526 } 527 //case x > y: 528 return 1 529} 530 531func collateUint(x, y uint64) int { 532 switch { 533 case x < y: 534 return -1 535 case x == y: 536 return 0 537 } 538 //case x > y: 539 return 1 540} 541 542func collateIntUint(x int64, y uint64) int { 543 if y > math.MaxInt64 { 544 return -1 545 } 546 547 return collateInt(x, int64(y)) 548} 549 550func collateUintInt(x uint64, y int64) int { 551 return -collateIntUint(y, x) 552} 553 554func collateType(i interface{}) (r interface{}, err error) { 555 switch x := i.(type) { 556 default: 557 return nil, fmt.Errorf("invalid collate type %T", x) 558 case nil: 559 return i, nil 560 case bool: 561 return i, nil 562 case int8: 563 return int64(x), nil 564 case int16: 565 return int64(x), nil 566 case int32: 567 return int64(x), nil 568 case int64: 569 return i, nil 570 case int: 571 return int64(x), nil 572 case uint8: 573 return uint64(x), nil 574 case uint16: 575 return uint64(x), nil 576 case uint32: 577 return uint64(x), nil 578 case uint64: 579 return i, nil 580 case uint: 581 return uint64(x), nil 582 case float32: 583 return float64(x), nil 584 case float64: 585 return i, nil 586 case complex64: 587 return complex128(x), nil 588 case complex128: 589 return i, nil 590 case []byte: 591 return i, nil 592 case string: 593 return i, nil 594 } 595} 596 597// Collate collates two arrays of Go predeclared scalar types (and the typeless 598// nil or []byte). If any other type appears in x or y, Collate will return a 599// non nil error. String items are collated using strCollate or lexically 600// byte-wise (as when using Go comparison operators) when strCollate is nil. 601// []byte items are collated using bytes.Compare. 602// 603// Collate returns: 604// 605// -1 if x < y 606// 0 if x == y 607// +1 if x > y 608// 609// The same value as defined above must be returned from strCollate. 610// 611// The "outer" ordering is: nil, bool, number, []byte, string. IOW, nil is 612// "smaller" than anything else except other nil, numbers collate before 613// []byte, []byte collate before strings, etc. 614// 615// Integers and real numbers collate as expected in math. However, complex 616// numbers are not ordered in Go. Here the ordering is defined: Complex numbers 617// are in comparison considered first only by their real part. Iff the result 618// is equality then the imaginary part is used to determine the ordering. In 619// this "second order" comparing, integers and real numbers are considered as 620// complex numbers with a zero imaginary part. 621func Collate(x, y []interface{}, strCollate func(string, string) int) (r int, err error) { 622 nx, ny := len(x), len(y) 623 624 switch { 625 case nx == 0 && ny != 0: 626 return -1, nil 627 case nx == 0 && ny == 0: 628 return 0, nil 629 case nx != 0 && ny == 0: 630 return 1, nil 631 } 632 633 r = 1 634 if nx > ny { 635 x, y, r = y, x, -r 636 } 637 638 var c int 639 for i, xi0 := range x { 640 yi0 := y[i] 641 xi, err := collateType(xi0) 642 if err != nil { 643 return 0, err 644 } 645 646 yi, err := collateType(yi0) 647 if err != nil { 648 return 0, err 649 } 650 651 switch x := xi.(type) { 652 default: 653 panic(fmt.Errorf("internal error: %T", x)) 654 655 case nil: 656 switch yi.(type) { 657 case nil: 658 // nop 659 default: 660 return -r, nil 661 } 662 663 case bool: 664 switch y := yi.(type) { 665 case nil: 666 return r, nil 667 case bool: 668 switch { 669 case !x && y: 670 return -r, nil 671 case x == y: 672 // nop 673 case x && !y: 674 return r, nil 675 } 676 default: 677 return -r, nil 678 } 679 680 case int64: 681 switch y := yi.(type) { 682 case nil, bool: 683 return r, nil 684 case int64: 685 c = collateInt(x, y) 686 case uint64: 687 c = collateIntUint(x, y) 688 case float64: 689 c = collateFloat(float64(x), y) 690 case complex128: 691 c = collateComplex(complex(float64(x), 0), y) 692 case []byte: 693 return -r, nil 694 case string: 695 return -r, nil 696 } 697 698 if c != 0 { 699 return c * r, nil 700 } 701 702 case uint64: 703 switch y := yi.(type) { 704 case nil, bool: 705 return r, nil 706 case int64: 707 c = collateUintInt(x, y) 708 case uint64: 709 c = collateUint(x, y) 710 case float64: 711 c = collateFloat(float64(x), y) 712 case complex128: 713 c = collateComplex(complex(float64(x), 0), y) 714 case []byte: 715 return -r, nil 716 case string: 717 return -r, nil 718 } 719 720 if c != 0 { 721 return c * r, nil 722 } 723 724 case float64: 725 switch y := yi.(type) { 726 case nil, bool: 727 return r, nil 728 case int64: 729 c = collateFloat(x, float64(y)) 730 case uint64: 731 c = collateFloat(x, float64(y)) 732 case float64: 733 c = collateFloat(x, y) 734 case complex128: 735 c = collateComplex(complex(x, 0), y) 736 case []byte: 737 return -r, nil 738 case string: 739 return -r, nil 740 } 741 742 if c != 0 { 743 return c * r, nil 744 } 745 746 case complex128: 747 switch y := yi.(type) { 748 case nil, bool: 749 return r, nil 750 case int64: 751 c = collateComplex(x, complex(float64(y), 0)) 752 case uint64: 753 c = collateComplex(x, complex(float64(y), 0)) 754 case float64: 755 c = collateComplex(x, complex(y, 0)) 756 case complex128: 757 c = collateComplex(x, y) 758 case []byte: 759 return -r, nil 760 case string: 761 return -r, nil 762 } 763 764 if c != 0 { 765 return c * r, nil 766 } 767 768 case []byte: 769 switch y := yi.(type) { 770 case nil, bool, int64, uint64, float64, complex128: 771 return r, nil 772 case []byte: 773 c = bytes.Compare(x, y) 774 case string: 775 return -r, nil 776 } 777 778 if c != 0 { 779 return c * r, nil 780 } 781 782 case string: 783 switch y := yi.(type) { 784 case nil, bool, int64, uint64, float64, complex128: 785 return r, nil 786 case []byte: 787 return r, nil 788 case string: 789 switch { 790 case strCollate != nil: 791 c = strCollate(x, y) 792 case x < y: 793 return -r, nil 794 case x == y: 795 c = 0 796 case x > y: 797 return r, nil 798 } 799 } 800 801 if c != 0 { 802 return c * r, nil 803 } 804 } 805 } 806 807 if nx == ny { 808 return 0, nil 809 } 810 811 return -r, nil 812} 813