Posted to tcl by sebres at Wed Feb 06 17:34:59 GMT 2019view raw

  1. ## ----------------------------------------------------------------------------
  2. ## utf-bytes-needed --
  3. ##
  4. ## Checks end of byte-array is fulfilled and returns how many bytes are needed
  5. ## to get complete utf-8 sequence.
  6. ## ----------------------------------------------------------------------------
  7.  
  8. variable totalBytes [split {
  9. 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  10. 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  11. 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  12. 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  13. 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  14. 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  15. 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
  16. 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
  17. 4,4,4,4,4,4,4,4,
  18. 1,1,1,1,1,1,1,1
  19. } ,]
  20. proc utf-bytes-needed {barr} {
  21. if {![string length $barr]} {return 0}
  22.  
  23. for {set i 0} {$i < 4} {incr i} {
  24. set look [string index $barr end-$i]
  25. if {$look eq ""} { #out of start
  26. incr i -1
  27. break;
  28. }
  29. binary scan $look cu b
  30. if {$b < 0x80} {
  31. break;
  32. }
  33. if {$b >= 0xC0} {
  34. break;
  35. }
  36. }
  37.  
  38. variable totalBytes
  39. expr {[lindex $totalBytes $b] - [incr i]}
  40. }
  41.  
  42. ## ----------------------------------------------------------------------
  43. ## Tests:
  44. ## ----------------------------------------------------------------------
  45.  
  46. foreach v {
  47. 0x24 {0xC2 0xA2} {0xE2 0x82 0xAC}
  48. {0xC2} {0xE2} {0xE2 0x82}
  49. } {
  50. # set v [list 0x41 0x42 0x43 {*}$v]
  51. set b [binary format [string repeat cu [llength $v]] {*}$v]
  52. set needed [utf-bytes-needed $b]
  53. puts [format "%-30s %-4s\t(%s)\t needs %d byte(s)" $v $b [encoding convertfrom utf-8 $b] $needed]
  54. }
  55.  
  56. ## ----------------------------------------------------------------------
  57. ## Results:
  58. ## ----------------------------------------------------------------------
  59.  
  60. # 0x24 $ ($) needs 0 byte(s)
  61. # 0xC2 0xA2 ¢ (¢) needs 0 byte(s)
  62. # 0xE2 0x82 0xAC € (¬) needs 0 byte(s)
  63. # 0xC2 Â (Â) needs 1 byte(s)
  64. # 0xE2 â (â) needs 2 byte(s)
  65. # 0xE2 0x82 ₠(â‚) needs 1 byte(s)
  66.