convert.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790
  1. // Copyright 2017 The Xorm 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. package xorm
  5. import (
  6. "bytes"
  7. "database/sql/driver"
  8. "encoding/binary"
  9. "errors"
  10. "fmt"
  11. "math"
  12. "reflect"
  13. "strconv"
  14. "time"
  15. )
  16. var errNilPtr = errors.New("destination pointer is nil") // embedded in descriptive error
  17. func strconvErr(err error) error {
  18. if ne, ok := err.(*strconv.NumError); ok {
  19. return ne.Err
  20. }
  21. return err
  22. }
  23. func cloneBytes(b []byte) []byte {
  24. if b == nil {
  25. return nil
  26. } else {
  27. c := make([]byte, len(b))
  28. copy(c, b)
  29. return c
  30. }
  31. }
  32. func asString(src interface{}) string {
  33. switch v := src.(type) {
  34. case string:
  35. return v
  36. case []byte:
  37. return string(v)
  38. }
  39. rv := reflect.ValueOf(src)
  40. switch rv.Kind() {
  41. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  42. return strconv.FormatInt(rv.Int(), 10)
  43. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  44. return strconv.FormatUint(rv.Uint(), 10)
  45. case reflect.Float64:
  46. return strconv.FormatFloat(rv.Float(), 'g', -1, 64)
  47. case reflect.Float32:
  48. return strconv.FormatFloat(rv.Float(), 'g', -1, 32)
  49. case reflect.Bool:
  50. return strconv.FormatBool(rv.Bool())
  51. }
  52. return fmt.Sprintf("%v", src)
  53. }
  54. func asBytes(buf []byte, rv reflect.Value) (b []byte, ok bool) {
  55. switch rv.Kind() {
  56. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  57. return strconv.AppendInt(buf, rv.Int(), 10), true
  58. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  59. return strconv.AppendUint(buf, rv.Uint(), 10), true
  60. case reflect.Float32:
  61. return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 32), true
  62. case reflect.Float64:
  63. return strconv.AppendFloat(buf, rv.Float(), 'g', -1, 64), true
  64. case reflect.Bool:
  65. return strconv.AppendBool(buf, rv.Bool()), true
  66. case reflect.String:
  67. s := rv.String()
  68. return append(buf, s...), true
  69. }
  70. return
  71. }
  72. // convertAssign copies to dest the value in src, converting it if possible.
  73. // An error is returned if the copy would result in loss of information.
  74. // dest should be a pointer type.
  75. func convertAssign(dest, src interface{}) error {
  76. // Common cases, without reflect.
  77. switch s := src.(type) {
  78. case string:
  79. switch d := dest.(type) {
  80. case *string:
  81. if d == nil {
  82. return errNilPtr
  83. }
  84. *d = s
  85. return nil
  86. case *[]byte:
  87. if d == nil {
  88. return errNilPtr
  89. }
  90. *d = []byte(s)
  91. return nil
  92. }
  93. case []byte:
  94. switch d := dest.(type) {
  95. case *string:
  96. if d == nil {
  97. return errNilPtr
  98. }
  99. *d = string(s)
  100. return nil
  101. case *interface{}:
  102. if d == nil {
  103. return errNilPtr
  104. }
  105. *d = cloneBytes(s)
  106. return nil
  107. case *[]byte:
  108. if d == nil {
  109. return errNilPtr
  110. }
  111. *d = cloneBytes(s)
  112. return nil
  113. }
  114. case time.Time:
  115. switch d := dest.(type) {
  116. case *string:
  117. *d = s.Format(time.RFC3339Nano)
  118. return nil
  119. case *[]byte:
  120. if d == nil {
  121. return errNilPtr
  122. }
  123. *d = []byte(s.Format(time.RFC3339Nano))
  124. return nil
  125. }
  126. case nil:
  127. switch d := dest.(type) {
  128. case *interface{}:
  129. if d == nil {
  130. return errNilPtr
  131. }
  132. *d = nil
  133. return nil
  134. case *[]byte:
  135. if d == nil {
  136. return errNilPtr
  137. }
  138. *d = nil
  139. return nil
  140. }
  141. }
  142. var sv reflect.Value
  143. switch d := dest.(type) {
  144. case *string:
  145. sv = reflect.ValueOf(src)
  146. switch sv.Kind() {
  147. case reflect.Bool,
  148. reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
  149. reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
  150. reflect.Float32, reflect.Float64:
  151. *d = asString(src)
  152. return nil
  153. }
  154. case *[]byte:
  155. sv = reflect.ValueOf(src)
  156. if b, ok := asBytes(nil, sv); ok {
  157. *d = b
  158. return nil
  159. }
  160. case *bool:
  161. bv, err := driver.Bool.ConvertValue(src)
  162. if err == nil {
  163. *d = bv.(bool)
  164. }
  165. return err
  166. case *interface{}:
  167. *d = src
  168. return nil
  169. }
  170. dpv := reflect.ValueOf(dest)
  171. if dpv.Kind() != reflect.Ptr {
  172. return errors.New("destination not a pointer")
  173. }
  174. if dpv.IsNil() {
  175. return errNilPtr
  176. }
  177. if !sv.IsValid() {
  178. sv = reflect.ValueOf(src)
  179. }
  180. dv := reflect.Indirect(dpv)
  181. if sv.IsValid() && sv.Type().AssignableTo(dv.Type()) {
  182. switch b := src.(type) {
  183. case []byte:
  184. dv.Set(reflect.ValueOf(cloneBytes(b)))
  185. default:
  186. dv.Set(sv)
  187. }
  188. return nil
  189. }
  190. if dv.Kind() == sv.Kind() && sv.Type().ConvertibleTo(dv.Type()) {
  191. dv.Set(sv.Convert(dv.Type()))
  192. return nil
  193. }
  194. switch dv.Kind() {
  195. case reflect.Ptr:
  196. if src == nil {
  197. dv.Set(reflect.Zero(dv.Type()))
  198. return nil
  199. }
  200. dv.Set(reflect.New(dv.Type().Elem()))
  201. return convertAssign(dv.Interface(), src)
  202. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  203. s := asString(src)
  204. i64, err := strconv.ParseInt(s, 10, dv.Type().Bits())
  205. if err != nil {
  206. err = strconvErr(err)
  207. return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err)
  208. }
  209. dv.SetInt(i64)
  210. return nil
  211. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  212. s := asString(src)
  213. u64, err := strconv.ParseUint(s, 10, dv.Type().Bits())
  214. if err != nil {
  215. err = strconvErr(err)
  216. return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err)
  217. }
  218. dv.SetUint(u64)
  219. return nil
  220. case reflect.Float32, reflect.Float64:
  221. s := asString(src)
  222. f64, err := strconv.ParseFloat(s, dv.Type().Bits())
  223. if err != nil {
  224. err = strconvErr(err)
  225. return fmt.Errorf("converting driver.Value type %T (%q) to a %s: %v", src, s, dv.Kind(), err)
  226. }
  227. dv.SetFloat(f64)
  228. return nil
  229. case reflect.String:
  230. dv.SetString(asString(src))
  231. return nil
  232. }
  233. return fmt.Errorf("unsupported Scan, storing driver.Value type %T into type %T", src, dest)
  234. }
  235. func asKind(vv reflect.Value, tp reflect.Type) (interface{}, error) {
  236. switch tp.Kind() {
  237. case reflect.Int64:
  238. return vv.Int(), nil
  239. case reflect.Int:
  240. return int(vv.Int()), nil
  241. case reflect.Int32:
  242. return int32(vv.Int()), nil
  243. case reflect.Int16:
  244. return int16(vv.Int()), nil
  245. case reflect.Int8:
  246. return int8(vv.Int()), nil
  247. case reflect.Uint64:
  248. return vv.Uint(), nil
  249. case reflect.Uint:
  250. return uint(vv.Uint()), nil
  251. case reflect.Uint32:
  252. return uint32(vv.Uint()), nil
  253. case reflect.Uint16:
  254. return uint16(vv.Uint()), nil
  255. case reflect.Uint8:
  256. return uint8(vv.Uint()), nil
  257. case reflect.String:
  258. return vv.String(), nil
  259. case reflect.Slice:
  260. if tp.Elem().Kind() == reflect.Uint8 {
  261. v, err := strconv.ParseInt(string(vv.Interface().([]byte)), 10, 64)
  262. if err != nil {
  263. return nil, err
  264. }
  265. return v, nil
  266. }
  267. }
  268. return nil, fmt.Errorf("unsupported primary key type: %v, %v", tp, vv)
  269. }
  270. func convertFloat(v interface{}) (float64, error) {
  271. switch v.(type) {
  272. case float32:
  273. return float64(v.(float32)), nil
  274. case float64:
  275. return v.(float64), nil
  276. case string:
  277. i, err := strconv.ParseFloat(v.(string), 64)
  278. if err != nil {
  279. return 0, err
  280. }
  281. return i, nil
  282. case []byte:
  283. i, err := strconv.ParseFloat(string(v.([]byte)), 64)
  284. if err != nil {
  285. return 0, err
  286. }
  287. return i, nil
  288. }
  289. return 0, fmt.Errorf("unsupported type: %v", v)
  290. }
  291. func convertInt(v interface{}) (int64, error) {
  292. switch v.(type) {
  293. case int:
  294. return int64(v.(int)), nil
  295. case int8:
  296. return int64(v.(int8)), nil
  297. case int16:
  298. return int64(v.(int16)), nil
  299. case int32:
  300. return int64(v.(int32)), nil
  301. case int64:
  302. return v.(int64), nil
  303. case []byte:
  304. i, err := strconv.ParseInt(string(v.([]byte)), 10, 64)
  305. if err != nil {
  306. return 0, err
  307. }
  308. return i, nil
  309. case string:
  310. i, err := strconv.ParseInt(v.(string), 10, 64)
  311. if err != nil {
  312. return 0, err
  313. }
  314. return i, nil
  315. }
  316. return 0, fmt.Errorf("unsupported type: %v", v)
  317. }
  318. func asBool(bs []byte) (bool, error) {
  319. if len(bs) == 0 {
  320. return false, nil
  321. }
  322. if bs[0] == 0x00 {
  323. return false, nil
  324. } else if bs[0] == 0x01 {
  325. return true, nil
  326. }
  327. return strconv.ParseBool(string(bs))
  328. }
  329. func EncodeString(s string) []byte {
  330. return []byte(s)
  331. }
  332. func DecodeToString(b []byte) string {
  333. return string(b)
  334. }
  335. func EncodeBool(b bool) []byte {
  336. if b == true {
  337. return []byte{1}
  338. } else {
  339. return []byte{0}
  340. }
  341. }
  342. func EncodeInt(i int) []byte {
  343. if i <= math.MaxInt8 {
  344. return EncodeInt8(int8(i))
  345. } else if i <= math.MaxInt16 {
  346. return EncodeInt16(int16(i))
  347. } else if i <= math.MaxInt32 {
  348. return EncodeInt32(int32(i))
  349. } else {
  350. return EncodeInt64(int64(i))
  351. }
  352. }
  353. func EncodeUint(i uint) []byte {
  354. if i <= math.MaxUint8 {
  355. return EncodeUint8(uint8(i))
  356. } else if i <= math.MaxUint16 {
  357. return EncodeUint16(uint16(i))
  358. } else if i <= math.MaxUint32 {
  359. return EncodeUint32(uint32(i))
  360. } else {
  361. return EncodeUint64(uint64(i))
  362. }
  363. }
  364. func EncodeInt8(i int8) []byte {
  365. return []byte{byte(i)}
  366. }
  367. func EncodeUint8(i uint8) []byte {
  368. return []byte{byte(i)}
  369. }
  370. func EncodeInt16(i int16) []byte {
  371. bytes := make([]byte, 2)
  372. binary.LittleEndian.PutUint16(bytes, uint16(i))
  373. return bytes
  374. }
  375. func EncodeUint16(i uint16) []byte {
  376. bytes := make([]byte, 2)
  377. binary.LittleEndian.PutUint16(bytes, i)
  378. return bytes
  379. }
  380. func EncodeInt32(i int32) []byte {
  381. bytes := make([]byte, 4)
  382. binary.LittleEndian.PutUint32(bytes, uint32(i))
  383. return bytes
  384. }
  385. func EncodeUint32(i uint32) []byte {
  386. bytes := make([]byte, 4)
  387. binary.LittleEndian.PutUint32(bytes, i)
  388. return bytes
  389. }
  390. func EncodeInt64(i int64) []byte {
  391. bytes := make([]byte, 8)
  392. binary.LittleEndian.PutUint64(bytes, uint64(i))
  393. return bytes
  394. }
  395. func EncodeUint64(i uint64) []byte {
  396. bytes := make([]byte, 8)
  397. binary.LittleEndian.PutUint64(bytes, i)
  398. return bytes
  399. }
  400. func EncodeFloat32(f float32) []byte {
  401. bits := math.Float32bits(f)
  402. bytes := make([]byte, 4)
  403. binary.LittleEndian.PutUint32(bytes, bits)
  404. return bytes
  405. }
  406. func EncodeFloat64(f float64) []byte {
  407. bits := math.Float64bits(f)
  408. bytes := make([]byte, 8)
  409. binary.LittleEndian.PutUint64(bytes, bits)
  410. return bytes
  411. }
  412. func Encode(vs ...interface{}) []byte {
  413. buf := new(bytes.Buffer)
  414. for i := 0; i < len(vs); i++ {
  415. switch value := vs[i].(type) {
  416. case int:
  417. buf.Write(EncodeInt(value))
  418. case int8:
  419. buf.Write(EncodeInt8(value))
  420. case int16:
  421. buf.Write(EncodeInt16(value))
  422. case int32:
  423. buf.Write(EncodeInt32(value))
  424. case int64:
  425. buf.Write(EncodeInt64(value))
  426. case uint:
  427. buf.Write(EncodeUint(value))
  428. case uint8:
  429. buf.Write(EncodeUint8(value))
  430. case uint16:
  431. buf.Write(EncodeUint16(value))
  432. case uint32:
  433. buf.Write(EncodeUint32(value))
  434. case uint64:
  435. buf.Write(EncodeUint64(value))
  436. case bool:
  437. buf.Write(EncodeBool(value))
  438. case string:
  439. buf.Write(EncodeString(value))
  440. case []byte:
  441. buf.Write(value)
  442. case float32:
  443. buf.Write(EncodeFloat32(value))
  444. case float64:
  445. buf.Write(EncodeFloat64(value))
  446. default:
  447. if err := binary.Write(buf, binary.LittleEndian, value); err != nil {
  448. buf.Write(EncodeString(fmt.Sprintf("%v", value)))
  449. }
  450. }
  451. }
  452. return buf.Bytes()
  453. }
  454. func IsNumeric(s string) bool {
  455. for i := 0; i < len(s); i++ {
  456. if s[i] < byte('0') || s[i] > byte('9') {
  457. return false
  458. }
  459. }
  460. return true
  461. }
  462. func Time(i interface{}, format string, TZLocation ...*time.Location) time.Time {
  463. s := String(i)
  464. t, _ := StrToTime(s, format, TZLocation...)
  465. return t
  466. }
  467. func StrToTime(str string, format string, TZLocation ...*time.Location) (time.Time, error) {
  468. if len(TZLocation) > 0 {
  469. if t, err := time.ParseInLocation(format, str, TZLocation[0]); err == nil {
  470. return t, nil
  471. } else {
  472. return time.Time{}, err
  473. }
  474. } else {
  475. if t, err := time.ParseInLocation(format, str, time.Local); err == nil {
  476. return t, nil
  477. } else {
  478. return time.Time{}, err
  479. }
  480. }
  481. }
  482. func TimeDuration(i interface{}) time.Duration {
  483. return time.Duration(Int64(i))
  484. }
  485. func Bytes(i interface{}) []byte {
  486. if i == nil {
  487. return nil
  488. }
  489. if r, ok := i.([]byte); ok {
  490. return r
  491. } else {
  492. return Encode(i)
  493. }
  494. }
  495. func String(i interface{}) string {
  496. if i == nil {
  497. return ""
  498. }
  499. switch value := i.(type) {
  500. case int:
  501. return strconv.Itoa(value)
  502. case int8:
  503. return strconv.Itoa(int(value))
  504. case int16:
  505. return strconv.Itoa(int(value))
  506. case int32:
  507. return strconv.Itoa(int(value))
  508. case int64:
  509. return strconv.Itoa(int(value))
  510. case uint:
  511. return strconv.FormatUint(uint64(value), 10)
  512. case uint8:
  513. return strconv.FormatUint(uint64(value), 10)
  514. case uint16:
  515. return strconv.FormatUint(uint64(value), 10)
  516. case uint32:
  517. return strconv.FormatUint(uint64(value), 10)
  518. case uint64:
  519. return strconv.FormatUint(uint64(value), 10)
  520. case float32:
  521. return strconv.FormatFloat(float64(value), 'f', -1, 32)
  522. case float64:
  523. return strconv.FormatFloat(value, 'f', -1, 64)
  524. case bool:
  525. return strconv.FormatBool(value)
  526. case string:
  527. return value
  528. case []byte:
  529. return string(value)
  530. default:
  531. return fmt.Sprintf("%v", value)
  532. }
  533. }
  534. func Strings(i interface{}) []string {
  535. if i == nil {
  536. return nil
  537. }
  538. if r, ok := i.([]string); ok {
  539. return r
  540. } else if r, ok := i.([]interface{}); ok {
  541. strs := make([]string, len(r))
  542. for k, v := range r {
  543. strs[k] = String(v)
  544. }
  545. return strs
  546. }
  547. return []string{fmt.Sprintf("%v", i)}
  548. }
  549. //false: "", 0, false, off
  550. func Bool(i interface{}) bool {
  551. if i == nil {
  552. return false
  553. }
  554. if v, ok := i.(bool); ok {
  555. return v
  556. }
  557. if s := String(i); s != "" && s != "0" && s != "false" && s != "off" {
  558. return true
  559. }
  560. return false
  561. }
  562. func Int(i interface{}) int {
  563. if i == nil {
  564. return 0
  565. }
  566. switch value := i.(type) {
  567. case int:
  568. return value
  569. case int8:
  570. return int(value)
  571. case int16:
  572. return int(value)
  573. case int32:
  574. return int(value)
  575. case int64:
  576. return int(value)
  577. case uint:
  578. return int(value)
  579. case uint8:
  580. return int(value)
  581. case uint16:
  582. return int(value)
  583. case uint32:
  584. return int(value)
  585. case uint64:
  586. return int(value)
  587. case float32:
  588. return int(value)
  589. case float64:
  590. return int(value)
  591. case bool:
  592. if value {
  593. return 1
  594. }
  595. return 0
  596. default:
  597. v, _ := strconv.Atoi(String(value))
  598. return v
  599. }
  600. }
  601. func Int8(i interface{}) int8 {
  602. if i == nil {
  603. return 0
  604. }
  605. if v, ok := i.(int8); ok {
  606. return v
  607. }
  608. return int8(Int(i))
  609. }
  610. func Int16(i interface{}) int16 {
  611. if i == nil {
  612. return 0
  613. }
  614. if v, ok := i.(int16); ok {
  615. return v
  616. }
  617. return int16(Int(i))
  618. }
  619. func Int32(i interface{}) int32 {
  620. if i == nil {
  621. return 0
  622. }
  623. if v, ok := i.(int32); ok {
  624. return v
  625. }
  626. return int32(Int(i))
  627. }
  628. func Int64(i interface{}) int64 {
  629. if i == nil {
  630. return 0
  631. }
  632. if v, ok := i.(int64); ok {
  633. return v
  634. }
  635. return int64(Int(i))
  636. }
  637. func Uint(i interface{}) uint {
  638. if i == nil {
  639. return 0
  640. }
  641. switch value := i.(type) {
  642. case int:
  643. return uint(value)
  644. case int8:
  645. return uint(value)
  646. case int16:
  647. return uint(value)
  648. case int32:
  649. return uint(value)
  650. case int64:
  651. return uint(value)
  652. case uint:
  653. return value
  654. case uint8:
  655. return uint(value)
  656. case uint16:
  657. return uint(value)
  658. case uint32:
  659. return uint(value)
  660. case uint64:
  661. return uint(value)
  662. case float32:
  663. return uint(value)
  664. case float64:
  665. return uint(value)
  666. case bool:
  667. if value {
  668. return 1
  669. }
  670. return 0
  671. default:
  672. v, _ := strconv.ParseUint(String(value), 10, 64)
  673. return uint(v)
  674. }
  675. }
  676. func Uint8(i interface{}) uint8 {
  677. if i == nil {
  678. return 0
  679. }
  680. if v, ok := i.(uint8); ok {
  681. return v
  682. }
  683. return uint8(Uint(i))
  684. }
  685. func Uint16(i interface{}) uint16 {
  686. if i == nil {
  687. return 0
  688. }
  689. if v, ok := i.(uint16); ok {
  690. return v
  691. }
  692. return uint16(Uint(i))
  693. }
  694. func Uint32(i interface{}) uint32 {
  695. if i == nil {
  696. return 0
  697. }
  698. if v, ok := i.(uint32); ok {
  699. return v
  700. }
  701. return uint32(Uint(i))
  702. }
  703. func Uint64(i interface{}) uint64 {
  704. if i == nil {
  705. return 0
  706. }
  707. if v, ok := i.(uint64); ok {
  708. return v
  709. }
  710. return uint64(Uint(i))
  711. }
  712. func Float32(i interface{}) float32 {
  713. if i == nil {
  714. return 0
  715. }
  716. if v, ok := i.(float32); ok {
  717. return v
  718. }
  719. v, _ := strconv.ParseFloat(String(i), 32)
  720. return float32(v)
  721. }
  722. func Float64(i interface{}) float64 {
  723. if i == nil {
  724. return 0
  725. }
  726. if v, ok := i.(float64); ok {
  727. return v
  728. }
  729. v, _ := strconv.ParseFloat(String(i), 64)
  730. return v
  731. }