/**
* File: $HeadURL: https://hdt-java.googlecode.com/svn/trunk/hdt-java/src/org/rdfhdt/hdt/util/string/ByteStringUtil.java $
* Revision: $Rev: 199 $
* Last modified: $Date: 2013-04-17 23:35:53 +0100 (mi, 17 abr 2013) $
* Last modified by: $Author: mario.arias $
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* Contacting the authors:
* Mario Arias: mario.arias@deri.org
* Javier D. Fernandez: jfergar@infor.uva.es
* Miguel A. Martinez-Prieto: migumar2@infor.uva.es
*/
package org.rdfhdt.hdt.util.string;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import org.rdfhdt.hdt.exceptions.NotImplementedException;
/**
* @author mario.arias
*
*/
public class ByteStringUtil {
private ByteStringUtil() {}
/**
* For use in the project when using String.getBytes() and making Strings from byte[]
*/
public static final Charset STRING_ENCODING = Charset.forName("UTF-8");
public static final String asString(byte [] buff, int offset) {
int len = strlen(buff, offset);
return new String(buff, offset, len, STRING_ENCODING);
}
public static final String asString(ByteBuffer buff, int offset) {
int len = strlen(buff, offset);
byte [] arr = new byte[len];
int i=0;
while(i<len) {
arr[i] = buff.get(offset+i);
i++;
}
return new String(arr, STRING_ENCODING);
}
public static final int strlen(byte [] buff, int off) {
int len = buff.length;
int pos = off;
while(pos<len && buff[pos]!=0) {
pos++;
}
return pos-off;
}
public static final int strlen(ByteBuffer buf, int base) {
int len=0;
int n=buf.capacity()-base;
while(len<n) {
if(buf.get(base+len)==0) {
return len;
}
len++;
}
throw new IllegalArgumentException("Buffer not Null-Terminated");
}
public static final int longestCommonPrefix(CharSequence str1, CharSequence str2) {
return longestCommonPrefix(str1, str2, 0);
}
public static final int longestCommonPrefix(CharSequence str1, CharSequence str2, int from) {
int len = Math.min(str1.length(), str2.length());
int delta = from;
while(delta<len && str1.charAt(delta)==str2.charAt(delta)) {
delta++;
}
return delta-from;
}
public static final int strcmp(CharSequence str, byte [] buff2, int off2) {
byte [] buff1;
int off1;
int len1;
int len2=buff2.length;
if(str instanceof CompactString) {
buff1 = ((CompactString) str).getData();
off1=0;
len1=buff1.length;
} else if(str instanceof String) {
buff1 = ((String) str).getBytes(ByteStringUtil.STRING_ENCODING);
off1=0;
len1=buff1.length;
} else if(str instanceof ReplazableString) {
buff1 = ((ReplazableString) str).buffer;
off1=0;
len1= ((ReplazableString) str).used;
} else {
throw new NotImplementedException();
}
int n = Math.min(len1-off1, len2-off2);
int p1 = off1;
int p2 = off2;
while( n-- != 0) {
int a = buff1[p1++] & 0xFF;
int b = buff2[p2++] & 0xFF;
if(a!=b) {
return a-b;
}
if(a==0) {
if(b==0) {
return 0;
} else {
return -1;
}
}
}
if(p1-off1<len1 && buff1[p1]!=0){
// Still remaining in string one, second is shorter
return 1;
}
if(p2-off2<len2 && buff2[p2]!=0){
// Still remaining in string two, first is shorter.
return -1;
}
return 0;
}
public static final int strcmp(CharSequence str, ByteBuffer buffer, int offset) {
byte [] buf=null;
int len;
if(str instanceof DelayedString) {
str = ((DelayedString) str).getInternal();
}
// Isolate array
if(str instanceof CompactString) {
buf = ((CompactString) str).getData();
len = buf.length;
} else if(str instanceof String) {
buf = ((String) str).getBytes(ByteStringUtil.STRING_ENCODING);
len = buf.length;
} else if(str instanceof ReplazableString) {
buf = ((ReplazableString) str).buffer;
len = ((ReplazableString) str).used;
} else {
throw new NotImplementedException();
}
// Compare
int i=0;
int n = Math.min(len, buffer.capacity()-offset);
while(i<n) {
int v1 = buf[i] & 0xFF;
int v2 = buffer.get(offset+i) & 0xFF;
if(v1!=v2) {
return v1-v2;
}
if(v1==0) {
return 0;
}
i++;
}
// One of the buffer exhausted
if(buffer.capacity()-offset-i>0) {
byte v = buffer.get(offset+i);
if(v==0) {
return 0;
} else {
return -1;
}
} else {
throw new IllegalArgumentException("Buffer is not Null-Terminated");
}
}
public static final int append(CharSequence str, int start, byte [] buffer, int bufpos) {
byte [] bytes;
int len;
if(str instanceof String) {
bytes = ((String) str).getBytes(ByteStringUtil.STRING_ENCODING);
len = bytes.length;
} else if(str instanceof CompactString) {
bytes = ((CompactString) str).getData();
len = bytes.length;
} else if(str instanceof ReplazableString) {
bytes = ((ReplazableString) str).getBuffer();
len = ((ReplazableString) str).used;
} else {
throw new NotImplementedException();
}
// System.arraycopy(bytes, start, buffer, bufpos, len - start);
// Write and remove null characters
int cur = start;
int ini = start;
int written = 0;
while(cur<len) {
if(bytes[cur]==0) {
// out.write(bytes, ini, cur-ini);
System.arraycopy(bytes, ini, buffer, bufpos+written, cur-ini);
written += (cur-ini);
ini = cur+1;
}
cur++;
}
if(ini<len) {
System.arraycopy(bytes, ini, buffer, bufpos+written, len-ini);
written += (len-ini);
}
return written;
}
public static final int append(OutputStream out, CharSequence str, int start) throws IOException {
byte [] bytes;
int len;
if(str instanceof String) {
bytes = ((String) str).getBytes(ByteStringUtil.STRING_ENCODING);
len = bytes.length;
} else if(str instanceof CompactString) {
bytes = ((CompactString) str).getData();
len = bytes.length;
} else if(str instanceof ReplazableString) {
bytes = ((ReplazableString) str).getBuffer();
len = ((ReplazableString) str).used;
} else {
throw new NotImplementedException();
}
// Write and remove null characters
int cur = start;
int ini = start;
int written = 0;
while(cur<len) {
if(bytes[cur]==0) {
out.write(bytes, ini, cur-ini);
written += (cur-ini);
ini = cur+1;
}
cur++;
}
if(ini<len) {
out.write(bytes, ini, len - ini);
written += (len-ini);
}
return written;
}
}