@@ -79,8 +79,7 @@ public static void setXAttr(String path, String name, String value, String encod
7979 * @throws IOException on any error
8080 */
8181 public static void setXAttr (String path , String name , byte [] value ) throws IOException {
82- Memory valueMem = bytesToMemory (value );
83- int retval = XAttr .INSTANCE .setxattr (path , name , valueMem , new size_t (valueMem .size ()), 0 );
82+ int retval = XAttr .INSTANCE .setxattr (path , name , value , new size_t (value .length ), 0 );
8483 if (retval != 0 ) {
8584 final int eno = Native .getLastError ();
8685 throw new IOException ("errno: " + eno );
@@ -126,9 +125,7 @@ public static void lSetXAttr(String path, String name, String value, String enco
126125 * @throws IOException on any error
127126 */
128127 public static void lSetXAttr (String path , String name , byte [] value ) throws IOException {
129- Memory valueMem = bytesToMemory (value );
130- final int retval = XAttr .INSTANCE .lsetxattr (path , name , valueMem ,
131- new size_t (valueMem .size ()), 0 );
128+ final int retval = XAttr .INSTANCE .lsetxattr (path , name , value , new size_t (value .length ), 0 );
132129 if (retval != 0 ) {
133130 final int eno = Native .getLastError ();
134131 throw new IOException ("errno: " + eno );
@@ -171,9 +168,7 @@ public static void fSetXAttr(int fd, String name, String value, String encoding)
171168 * @throws IOException on any error
172169 */
173170 public static void fSetXAttr (int fd , String name , byte [] value ) throws IOException {
174- Memory valueMem = bytesToMemory (value );
175- final int retval = XAttr .INSTANCE .fsetxattr (fd , name , valueMem , new size_t (valueMem .size ()),
176- 0 );
171+ final int retval = XAttr .INSTANCE .fsetxattr (fd , name , value , new size_t (value .length ), 0 );
177172 if (retval != 0 ) {
178173 final int eno = Native .getLastError ();
179174 throw new IOException ("errno: " + eno );
@@ -203,10 +198,8 @@ public static String getXAttr(String path, String name) throws IOException {
203198 * @throws IOException on any error except <code>ERANGE</code> which handled internally
204199 */
205200 public static String getXAttr (String path , String name , String encoding ) throws IOException {
206- Memory valueMem = getXAttrAsMemory (path , name );
207- return Charset .forName (encoding )
208- .decode (valueMem .getByteBuffer (0 , valueMem .size ()))
209- .toString ();
201+ byte [] valueMem = getXAttrBytes (path , name );
202+ return new String (valueMem , Charset .forName (encoding ));
210203 }
211204
212205 /**
@@ -218,8 +211,28 @@ public static String getXAttr(String path, String name, String encoding) throws
218211 * @throws IOException on any error except <code>ERANGE</code> which handled internally
219212 */
220213 public static byte [] getXAttrBytes (String path , String name ) throws IOException {
221- Memory valueMem = getXAttrAsMemory (path , name );
222- return valueMem .getByteArray (0 , (int ) valueMem .size ());
214+ ssize_t retval ;
215+ byte [] valueMem ;
216+ int eno = 0 ;
217+
218+ do {
219+ retval = XAttr .INSTANCE .getxattr (path , name , (byte []) null , size_t .ZERO );
220+ if (retval .longValue () < 0 ) {
221+ eno = Native .getLastError ();
222+ throw new IOException ("errno: " + eno );
223+ }
224+
225+ valueMem = new byte [retval .intValue ()];
226+ retval = XAttr .INSTANCE .getxattr (path , name , valueMem , new size_t (valueMem .length ));
227+ if (retval .longValue () < 0 ) {
228+ eno = Native .getLastError ();
229+ if (eno != XAttr .ERANGE ) {
230+ throw new IOException ("errno: " + eno );
231+ }
232+ }
233+ } while (retval .longValue () < 0 && eno == XAttr .ERANGE );
234+
235+ return valueMem ;
223236 }
224237
225238 /**
@@ -236,7 +249,7 @@ public static Memory getXAttrAsMemory(String path, String name) throws IOExcepti
236249 int eno = 0 ;
237250
238251 do {
239- retval = XAttr .INSTANCE .getxattr (path , name , null , size_t .ZERO );
252+ retval = XAttr .INSTANCE .getxattr (path , name , ( Memory ) null , size_t .ZERO );
240253 if (retval .longValue () < 0 ) {
241254 eno = Native .getLastError ();
242255 throw new IOException ("errno: " + eno );
@@ -280,10 +293,8 @@ public static String lGetXAttr(String path, String name) throws IOException {
280293 * @throws IOException on any error except <code>ERANGE</code> which handled internally
281294 */
282295 public static String lGetXAttr (String path , String name , String encoding ) throws IOException {
283- Memory valueMem = lGetXAttrAsMemory (path , name );
284- return Charset .forName (encoding )
285- .decode (valueMem .getByteBuffer (0 , valueMem .size ()))
286- .toString ();
296+ byte [] valueMem = lGetXAttrBytes (path , name );
297+ return new String (valueMem , Charset .forName (encoding ));
287298 }
288299
289300 /**
@@ -296,8 +307,28 @@ public static String lGetXAttr(String path, String name, String encoding) throws
296307 * @throws IOException on any error except <code>ERANGE</code> which handled internally
297308 */
298309 public static byte [] lGetXAttrBytes (String path , String name ) throws IOException {
299- Memory valueMem = lGetXAttrAsMemory (path , name );
300- return valueMem .getByteArray (0 , (int ) valueMem .size ());
310+ ssize_t retval ;
311+ byte [] valueMem ;
312+ int eno = 0 ;
313+
314+ do {
315+ retval = XAttr .INSTANCE .lgetxattr (path , name , (byte []) null , size_t .ZERO );
316+ if (retval .longValue () < 0 ) {
317+ eno = Native .getLastError ();
318+ throw new IOException ("errno: " + eno );
319+ }
320+
321+ valueMem = new byte [retval .intValue ()];
322+ retval = XAttr .INSTANCE .lgetxattr (path , name , valueMem , new size_t (valueMem .length ));
323+ if (retval .longValue () < 0 ) {
324+ eno = Native .getLastError ();
325+ if (eno != XAttr .ERANGE ) {
326+ throw new IOException ("errno: " + eno );
327+ }
328+ }
329+ } while (retval .longValue () < 0 && eno == XAttr .ERANGE );
330+
331+ return valueMem ;
301332 }
302333
303334 /**
@@ -315,7 +346,7 @@ public static Memory lGetXAttrAsMemory(String path, String name) throws IOExcept
315346 int eno = 0 ;
316347
317348 do {
318- retval = XAttr .INSTANCE .lgetxattr (path , name , null , size_t .ZERO );
349+ retval = XAttr .INSTANCE .lgetxattr (path , name , ( Memory ) null , size_t .ZERO );
319350 if (retval .longValue () < 0 ) {
320351 eno = Native .getLastError ();
321352 throw new IOException ("errno: " + eno );
@@ -357,10 +388,8 @@ public static String fGetXAttr(int fd, String name) throws IOException {
357388 * @throws IOException on any error except <code>ERANGE</code> which handled internally
358389 */
359390 public static String fGetXAttr (int fd , String name , String encoding ) throws IOException {
360- Memory valueMem = fGetXAttrAsMemory (fd , name );
361- return Charset .forName (encoding )
362- .decode (valueMem .getByteBuffer (0 , valueMem .size ()))
363- .toString ();
391+ byte [] valueMem = fGetXAttrBytes (fd , name );
392+ return new String (valueMem , Charset .forName (encoding ));
364393 }
365394
366395 /**
@@ -372,8 +401,28 @@ public static String fGetXAttr(int fd, String name, String encoding) throws IOEx
372401 * @throws IOException on any error except <code>ERANGE</code> which handled internally
373402 */
374403 public static byte [] fGetXAttrBytes (int fd , String name ) throws IOException {
375- Memory valueMem = fGetXAttrAsMemory (fd , name );
376- return valueMem .getByteArray (0 , (int ) valueMem .size ());
404+ ssize_t retval ;
405+ byte [] valueMem ;
406+ int eno = 0 ;
407+
408+ do {
409+ retval = XAttr .INSTANCE .fgetxattr (fd , name , (byte []) null , size_t .ZERO );
410+ if (retval .longValue () < 0 ) {
411+ eno = Native .getLastError ();
412+ throw new IOException ("errno: " + eno );
413+ }
414+
415+ valueMem = new byte [retval .intValue ()];
416+ retval = XAttr .INSTANCE .fgetxattr (fd , name , valueMem , new size_t (valueMem .length ));
417+ if (retval .longValue () < 0 ) {
418+ eno = Native .getLastError ();
419+ if (eno != XAttr .ERANGE ) {
420+ throw new IOException ("errno: " + eno );
421+ }
422+ }
423+ } while (retval .longValue () < 0 && eno == XAttr .ERANGE );
424+
425+ return valueMem ;
377426 }
378427
379428 /**
@@ -390,7 +439,7 @@ public static Memory fGetXAttrAsMemory(int fd, String name) throws IOException {
390439 int eno = 0 ;
391440
392441 do {
393- retval = XAttr .INSTANCE .fgetxattr (fd , name , null , size_t .ZERO );
442+ retval = XAttr .INSTANCE .fgetxattr (fd , name , ( Memory ) null , size_t .ZERO );
394443 if (retval .longValue () < 0 ) {
395444 eno = Native .getLastError ();
396445 throw new IOException ("errno: " + eno );
@@ -431,18 +480,18 @@ public static Collection<String> listXAttr(String path) throws IOException {
431480 */
432481 public static Collection <String > listXAttr (String path , String encoding ) throws IOException {
433482 ssize_t retval ;
434- Memory listMem ;
483+ byte [] listMem ;
435484 int eno = 0 ;
436485
437486 do {
438- retval = XAttr .INSTANCE .listxattr (path , null , size_t .ZERO );
487+ retval = XAttr .INSTANCE .listxattr (path , ( byte []) null , size_t .ZERO );
439488 if (retval .longValue () < 0 ) {
440489 eno = Native .getLastError ();
441490 throw new IOException ("errno: " + eno );
442491 }
443492
444- listMem = new Memory ( retval .longValue ()) ;
445- retval = XAttr .INSTANCE .listxattr (path , listMem , new size_t (listMem .size () ));
493+ listMem = new byte [ retval .intValue ()] ;
494+ retval = XAttr .INSTANCE .listxattr (path , listMem , new size_t (listMem .length ));
446495 if (retval .longValue () < 0 ) {
447496 eno = Native .getLastError ();
448497 if (eno != XAttr .ERANGE ) {
@@ -478,18 +527,18 @@ public static Collection<String> lListXAttr(String path) throws IOException {
478527 */
479528 public static Collection <String > lListXAttr (String path , String encoding ) throws IOException {
480529 ssize_t retval ;
481- Memory listMem ;
530+ byte [] listMem ;
482531 int eno = 0 ;
483532
484533 do {
485- retval = XAttr .INSTANCE .llistxattr (path , null , size_t .ZERO );
534+ retval = XAttr .INSTANCE .llistxattr (path , ( byte []) null , size_t .ZERO );
486535 if (retval .longValue () < 0 ) {
487536 eno = Native .getLastError ();
488537 throw new IOException ("errno: " + eno );
489538 }
490539
491- listMem = new Memory ( retval .longValue ()) ;
492- retval = XAttr .INSTANCE .llistxattr (path , listMem , new size_t (listMem .size () ));
540+ listMem = new byte [ retval .intValue ()] ;
541+ retval = XAttr .INSTANCE .llistxattr (path , listMem , new size_t (listMem .length ));
493542 if (retval .longValue () < 0 ) {
494543 eno = Native .getLastError ();
495544 if (eno != XAttr .ERANGE ) {
@@ -523,18 +572,18 @@ public static Collection<String> fListXAttr(int fd) throws IOException {
523572 */
524573 public static Collection <String > fListXAttr (int fd , String encoding ) throws IOException {
525574 ssize_t retval ;
526- Memory listMem ;
575+ byte [] listMem ;
527576 int eno = 0 ;
528577
529578 do {
530- retval = XAttr .INSTANCE .flistxattr (fd , null , size_t .ZERO );
579+ retval = XAttr .INSTANCE .flistxattr (fd , ( byte []) null , size_t .ZERO );
531580 if (retval .longValue () < 0 ) {
532581 eno = Native .getLastError ();
533582 throw new IOException ("errno: " + eno );
534583 }
535584
536- listMem = new Memory ( retval .longValue ()) ;
537- retval = XAttr .INSTANCE .flistxattr (fd , listMem , new size_t (listMem .size () ));
585+ listMem = new byte [ retval .intValue ()] ;
586+ retval = XAttr .INSTANCE .flistxattr (fd , listMem , new size_t (listMem .length ));
538587 if (retval .longValue () < 0 ) {
539588 eno = Native .getLastError ();
540589 if (eno != XAttr .ERANGE ) {
@@ -593,33 +642,19 @@ public static void fRemoveXAttr(int fd, String name) throws IOException {
593642 }
594643 }
595644
596- private static Memory bytesToMemory (byte [] value ) {
597- Memory valueMem = new Memory (value .length );
598- valueMem .write (0 , value , 0 , value .length );
599- return valueMem ;
600- }
601-
602- private static Collection <String > splitBufferToStrings (Memory valueMem , String encoding )
645+ private static Collection <String > splitBufferToStrings (byte [] valueMem , String encoding )
603646 throws IOException {
604647 final Charset charset = Charset .forName (encoding );
605648 final Set <String > attributesList = new LinkedHashSet <String >(1 );
606- long offset = 0 ;
607- while (offset != valueMem .size ()) {
608- // Find terminating NUL character.
609- long nulOffset = valueMem .indexOf (offset , (byte ) 0 );
610- if (nulOffset == -1 ) {
611- throw new IOException ("Expected NUL character not found." );
649+ int offset = 0 ;
650+ for (int i = 0 ; i < valueMem .length ; i ++) {
651+ // each entry is terminated by a single \0 byte
652+ if (valueMem [i ] == 0 ) {
653+ // Convert bytes of the name to String.
654+ final String name = new String (valueMem , offset , i - offset , charset );
655+ attributesList .add (name );
656+ offset = i + 1 ;
612657 }
613-
614- // Duplicate buffer with limit at end of name.
615- final ByteBuffer nameBuffer = valueMem .getByteBuffer (offset , nulOffset );
616-
617- // Convert bytes of the name to String.
618- final String name = charset .decode (nameBuffer ).toString ();
619- attributesList .add (name );
620-
621- // Move past NUL.
622- offset += nulOffset + 1 ;
623658 }
624659 return attributesList ;
625660 }
0 commit comments