26
26
package jdk .internal .foreign ;
27
27
28
28
import java .lang .foreign .MemorySegment ;
29
- import java .lang .foreign .ValueLayout ;
30
29
import java .nio .charset .Charset ;
31
30
import java .nio .charset .StandardCharsets ;
32
31
33
32
import static java .lang .foreign .ValueLayout .JAVA_BYTE ;
34
33
import static java .lang .foreign .ValueLayout .JAVA_SHORT ;
34
+ import static java .lang .foreign .ValueLayout .JAVA_INT ;
35
35
36
36
/**
37
37
* Miscellaneous functions to read and write strings, in various charsets.
@@ -41,6 +41,7 @@ public static String read(MemorySegment segment, long offset, Charset charset) {
41
41
return switch (CharsetKind .of (charset )) {
42
42
case SINGLE_BYTE -> readFast_byte (segment , offset , charset );
43
43
case DOUBLE_BYTE -> readFast_short (segment , offset , charset );
44
+ case QUAD_BYTE -> readFast_int (segment , offset , charset );
44
45
default -> throw new UnsupportedOperationException ("Unsupported charset: " + charset );
45
46
};
46
47
}
@@ -49,26 +50,27 @@ public static void write(MemorySegment segment, long offset, Charset charset, St
49
50
switch (CharsetKind .of (charset )) {
50
51
case SINGLE_BYTE -> writeFast_byte (segment , offset , charset , string );
51
52
case DOUBLE_BYTE -> writeFast_short (segment , offset , charset , string );
53
+ case QUAD_BYTE -> writeFast_int (segment , offset , charset , string );
52
54
default -> throw new UnsupportedOperationException ("Unsupported charset: " + charset );
53
55
}
54
56
}
55
57
private static String readFast_byte (MemorySegment segment , long offset , Charset charset ) {
56
58
long len = strlen_byte (segment , offset );
57
59
byte [] bytes = new byte [(int )len ];
58
- MemorySegment .copy (segment , ValueLayout . JAVA_BYTE , offset , bytes , 0 , (int )len );
60
+ MemorySegment .copy (segment , JAVA_BYTE , offset , bytes , 0 , (int )len );
59
61
return new String (bytes , charset );
60
62
}
61
63
62
64
private static void writeFast_byte (MemorySegment segment , long offset , Charset charset , String string ) {
63
65
byte [] bytes = string .getBytes (charset );
64
- MemorySegment .copy (bytes , 0 , segment , ValueLayout . JAVA_BYTE , offset , bytes .length );
65
- segment .set (ValueLayout . JAVA_BYTE , offset + bytes .length , (byte )0 );
66
+ MemorySegment .copy (bytes , 0 , segment , JAVA_BYTE , offset , bytes .length );
67
+ segment .set (JAVA_BYTE , offset + bytes .length , (byte )0 );
66
68
}
67
69
68
70
private static String readFast_short (MemorySegment segment , long offset , Charset charset ) {
69
71
long len = strlen_short (segment , offset );
70
72
byte [] bytes = new byte [(int )len ];
71
- MemorySegment .copy (segment , ValueLayout . JAVA_BYTE , offset , bytes , 0 , (int )len );
73
+ MemorySegment .copy (segment , JAVA_BYTE , offset , bytes , 0 , (int )len );
72
74
return new String (bytes , charset );
73
75
}
74
76
@@ -78,6 +80,19 @@ private static void writeFast_short(MemorySegment segment, long offset, Charset
78
80
segment .set (JAVA_SHORT , offset + bytes .length , (short )0 );
79
81
}
80
82
83
+ private static String readFast_int (MemorySegment segment , long offset , Charset charset ) {
84
+ long len = strlen_int (segment , offset );
85
+ byte [] bytes = new byte [(int )len ];
86
+ MemorySegment .copy (segment , JAVA_BYTE , offset , bytes , 0 , (int )len );
87
+ return new String (bytes , charset );
88
+ }
89
+
90
+ private static void writeFast_int (MemorySegment segment , long offset , Charset charset , String string ) {
91
+ byte [] bytes = string .getBytes (charset );
92
+ MemorySegment .copy (bytes , 0 , segment , JAVA_BYTE , offset , bytes .length );
93
+ segment .set (JAVA_INT , offset + bytes .length , 0 );
94
+ }
95
+
81
96
private static int strlen_byte (MemorySegment segment , long start ) {
82
97
// iterate until overflow (String can only hold a byte[], whose length can be expressed as an int)
83
98
for (int offset = 0 ; offset >= 0 ; offset ++) {
@@ -100,9 +115,21 @@ private static int strlen_short(MemorySegment segment, long start) {
100
115
throw new IllegalArgumentException ("String too large" );
101
116
}
102
117
118
+ private static int strlen_int (MemorySegment segment , long start ) {
119
+ // iterate until overflow (String can only hold a byte[], whose length can be expressed as an int)
120
+ for (int offset = 0 ; offset >= 0 ; offset += 4 ) {
121
+ int curr = segment .get (JAVA_INT , start + offset );
122
+ if (curr == 0 ) {
123
+ return offset ;
124
+ }
125
+ }
126
+ throw new IllegalArgumentException ("String too large" );
127
+ }
128
+
103
129
public enum CharsetKind {
104
130
SINGLE_BYTE (1 ),
105
- DOUBLE_BYTE (2 );
131
+ DOUBLE_BYTE (2 ),
132
+ QUAD_BYTE (4 );
106
133
107
134
final int terminatorCharSize ;
108
135
@@ -119,6 +146,8 @@ public static CharsetKind of(Charset charset) {
119
146
return CharsetKind .SINGLE_BYTE ;
120
147
} else if (charset == StandardCharsets .UTF_16LE || charset == StandardCharsets .UTF_16BE || charset == StandardCharsets .UTF_16 ) {
121
148
return CharsetKind .DOUBLE_BYTE ;
149
+ } else if (charset == StandardCharsets .UTF_32LE || charset == StandardCharsets .UTF_32BE || charset == StandardCharsets .UTF_32 ) {
150
+ return CharsetKind .QUAD_BYTE ;
122
151
} else {
123
152
throw new UnsupportedOperationException ("Unsupported charset: " + charset );
124
153
}
0 commit comments