/ *
XOWA: the XOWA Offline Wiki Application
Copyright ( C ) 2012 - 2017 gnosygnu @gmail.com
XOWA is licensed under the terms of the General Public License ( GPL ) Version 3 ,
or alternatively under the terms of the Apache License Version 2.0 .
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case - by - case basis .
The terms of each license can be found in the source code repository :
GPLv3 License : https : //github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License : https : //github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
* /
package gplx ;
import gplx.core.brys.* ;
public class Bry_split_ {
private static final Object thread_lock = new Object ( ) ;
public static byte [ ] [ ] Split ( byte [ ] src , byte dlm ) { return Split ( src , dlm , false ) ; }
public static byte [ ] [ ] Split ( byte [ ] src , byte dlm , boolean trim ) { return src = = null ? Bry_ . Ary_empty : Split ( src , 0 , src . length , dlm , trim ) ; }
public static byte [ ] [ ] Split ( byte [ ] src , int bgn , int end , byte dlm , boolean trim ) {
synchronized ( thread_lock ) {
Bry_split_wkr__to_ary wkr = Bry_split_wkr__to_ary . Instance ;
Split ( src , bgn , end , dlm , trim , wkr ) ;
return wkr . To_ary ( ) ;
}
}
public static int Split ( byte [ ] src , int src_bgn , int src_end , byte dlm , boolean trim , Bry_split_wkr wkr ) {
if ( src = = null | | src_end - src_bgn < 1 ) return 0 ;
int pos = src_bgn ;
int itm_bgn = - 1 , itm_end = - 1 ;
int count = 0 ;
while ( true ) {
boolean pos_is_last = pos = = src_end ;
byte b = pos_is_last ? dlm : src [ pos ] ;
int nxt_pos = pos + 1 ;
boolean process = true ;
switch ( b ) {
case Byte_ascii . Space : case Byte_ascii . Tab : case Byte_ascii . Nl : case Byte_ascii . Cr : // ignore ws; assumes that flags have no ws (they are single char) and vnts have no ws (EX: zh-hans)
if ( trim & & b ! = dlm ) process = false ; // b != dlm handles cases where ws is dlm, but trim is enabled; EX: " a \n b" -> "a", "b"
break ;
}
if ( process ) {
if ( b = = dlm ) {
boolean reset = true ;
if ( itm_bgn = = - 1 ) {
if ( pos_is_last ) { } // skip dlm at bgn / end; EX: "a,"
else { wkr . Split ( src , pos , pos ) ; } // else, process "empty" dlm; EX: ",a"
}
else {
int rv = wkr . Split ( src , itm_bgn , itm_end ) ;
switch ( rv ) {
case Rv__ok : + + count ; break ;
case Rv__extend : reset = false ; break ;
case Rv__cancel : return count ;
default : throw Err_ . new_unhandled ( rv ) ;
}
}
if ( reset ) itm_bgn = itm_end = - 1 ;
}
else {
if ( itm_bgn = = - 1 ) itm_bgn = pos ;
itm_end = nxt_pos ;
}
}
if ( pos_is_last ) break ;
pos = nxt_pos ;
}
return count ;
}
public static byte [ ] [ ] Split ( byte [ ] src , byte [ ] dlm ) { return Split ( src , 0 , src . length , dlm ) ; }
public static byte [ ] [ ] Split ( byte [ ] src , int src_bgn , int src_end , byte [ ] dlm ) {
if ( src = = null ) return Bry_ . Ary_empty ;
int src_len = src . length ;
if ( src_len = = 0 ) return Bry_ . Ary_empty ;
int cur_pos = src_bgn , dlm_len = dlm . length ;
List_adp rv = List_adp_ . New ( ) ;
while ( true ) {
int find_pos = Bry_find_ . Find_fwd ( src , dlm , cur_pos ) ;
if ( find_pos = = Bry_find_ . Not_found ) {
if ( cur_pos > = src_end ) break ; // dlm is last sequence in src; do not create empty itm
find_pos = src_end ;
}
rv . Add ( Bry_ . Mid ( src , cur_pos , find_pos ) ) ;
cur_pos = find_pos + dlm_len ;
if ( cur_pos > = src_end ) break ;
}
return ( byte [ ] [ ] ) rv . To_ary ( byte [ ] . class ) ;
}
public static byte [ ] [ ] Split_lines ( byte [ ] src ) {
if ( Bry_ . Len_eq_0 ( src ) ) return Bry_ . Ary_empty ;
int src_len = src . length , src_pos = 0 , fld_bgn = 0 ;
List_adp rv = List_adp_ . New ( ) ;
while ( true ) {
boolean last = src_pos = = src_len ;
byte b = last ? Byte_ascii . Nl : src [ src_pos ] ;
int nxt_bgn = src_pos + 1 ;
switch ( b ) {
case Byte_ascii . Cr :
case Byte_ascii . Nl :
if ( b = = Byte_ascii . Cr // check for crlf
& & nxt_bgn < src_len & & src [ nxt_bgn ] = = Byte_ascii . Nl ) {
+ + nxt_bgn ;
}
if ( last & & ( src_pos - fld_bgn = = 0 ) ) { } // ignore trailing itms
else
rv . Add ( Bry_ . Mid ( src , fld_bgn , src_pos ) ) ;
fld_bgn = nxt_bgn ;
break ;
}
if ( last ) break ;
src_pos = nxt_bgn ;
}
return ( byte [ ] [ ] ) rv . To_ary ( byte [ ] . class ) ;
}
public static byte [ ] [ ] Split_w_max ( byte [ ] src , byte dlm , int max ) {
byte [ ] [ ] rv = new byte [ max ] [ ] ;
int src_len = src . length ;
int rv_idx = 0 ;
int itm_bgn = 0 ;
int src_pos = 0 ;
while ( true ) {
boolean is_last = src_pos = = src_len ;
byte b = is_last ? dlm : src [ src_pos ] ;
if ( b = = dlm ) {
rv [ rv_idx + + ] = Bry_ . Mid ( src , itm_bgn , src_pos ) ;
itm_bgn = src_pos + 1 ;
}
if ( is_last | | rv_idx = = max )
break ;
else
src_pos + + ;
}
return rv ;
}
public static final int Rv__ok = 0 , Rv__extend = 1 , Rv__cancel = 2 ;
}
class Bry_split_wkr__to_ary implements gplx . core . brys . Bry_split_wkr {
private final List_adp list = List_adp_ . New ( ) ;
public int Split ( byte [ ] src , int itm_bgn , int itm_end ) {
synchronized ( list ) {
byte [ ] bry = itm_end = = itm_bgn ? Bry_ . Empty : Bry_ . Mid ( src , itm_bgn , itm_end ) ;
list . Add ( bry ) ;
return Bry_split_ . Rv__ok ;
}
}
public byte [ ] [ ] To_ary ( ) {
synchronized ( list ) {
return ( byte [ ] [ ] ) list . To_ary_and_clear ( byte [ ] . class ) ;
}
}
public static final Bry_split_wkr__to_ary Instance = new Bry_split_wkr__to_ary ( ) ; Bry_split_wkr__to_ary ( ) { }
}