string.goc 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. // Copyright 2009, 2010 The Go 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 runtime
  5. #include "runtime.h"
  6. #include "arch.h"
  7. #include "malloc.h"
  8. #include "go-string.h"
  9. #define charntorune(pv, str, len) __go_get_rune(str, len, pv)
  10. const String runtime_emptystring;
  11. intgo
  12. runtime_findnull(const byte *s)
  13. {
  14. if(s == nil)
  15. return 0;
  16. return __builtin_strlen((const char*) s);
  17. }
  18. intgo
  19. runtime_findnullw(const uint16 *s)
  20. {
  21. intgo l;
  22. if(s == nil)
  23. return 0;
  24. for(l=0; s[l]!=0; l++)
  25. ;
  26. return l;
  27. }
  28. static String
  29. gostringsize(intgo l, byte** pmem)
  30. {
  31. String s;
  32. byte *mem;
  33. if(l == 0) {
  34. *pmem = nil;
  35. return runtime_emptystring;
  36. }
  37. mem = runtime_mallocgc(l, 0, FlagNoScan|FlagNoZero);
  38. s.str = mem;
  39. s.len = l;
  40. *pmem = mem;
  41. return s;
  42. }
  43. String
  44. runtime_gostring(const byte *str)
  45. {
  46. intgo l;
  47. String s;
  48. byte *mem;
  49. l = runtime_findnull(str);
  50. s = gostringsize(l, &mem);
  51. runtime_memmove(mem, str, l);
  52. return s;
  53. }
  54. String
  55. runtime_gostringnocopy(const byte *str)
  56. {
  57. String s;
  58. s.str = str;
  59. s.len = runtime_findnull(str);
  60. return s;
  61. }
  62. func cstringToGo(str *byte) (s String) {
  63. s = runtime_gostringnocopy(str);
  64. }
  65. enum
  66. {
  67. Runeself = 0x80,
  68. };
  69. func stringiter(s String, k int) (retk int) {
  70. int32 l;
  71. if(k >= s.len) {
  72. // retk=0 is end of iteration
  73. retk = 0;
  74. goto out;
  75. }
  76. l = s.str[k];
  77. if(l < Runeself) {
  78. retk = k+1;
  79. goto out;
  80. }
  81. // multi-char rune
  82. retk = k + charntorune(&l, s.str+k, s.len-k);
  83. out:
  84. }
  85. func stringiter2(s String, k int) (retk int, retv int32) {
  86. if(k >= s.len) {
  87. // retk=0 is end of iteration
  88. retk = 0;
  89. retv = 0;
  90. goto out;
  91. }
  92. retv = s.str[k];
  93. if(retv < Runeself) {
  94. retk = k+1;
  95. goto out;
  96. }
  97. // multi-char rune
  98. retk = k + charntorune(&retv, s.str+k, s.len-k);
  99. out:
  100. }