Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
BEGIN LICENSE BLOCK ***** Version: CPL 1.0/GPL 2.0/LGPL 2.1 The contents of this file are subject to the Common Public License Version 1.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.eclipse.org/legal/cpl-v10.html Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. Copyright (C) 2007, 2008 Ola Bini <ola@ologix.com> Alternatively, the contents of this file may be used under the terms of either of the GNU General Public License Version 2 or later (the "GPL"), or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), in which case the provisions of the GPL or the LGPL are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of either the GPL or the LGPL, and not to allow others to use your version of this file under the terms of the CPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL or the LGPL. If you do not delete the provisions above, a recipient may use your version of this file under the terms of any one of the CPL, the GPL or the LGPL. END LICENSE BLOCK ***
 
 package org.jruby.util;
 
 import java.io.File;
 import java.util.List;
 
This class exists as a counterpart to the dir.c file in MRI source. It contains many methods useful for File matching and Globbing.

Author(s):
Ola Bini
 
 public class Dir {
     public final static boolean DOSISH = .;
     public final static boolean CASEFOLD_FILESYSTEM = ;
 
     public final static int FNM_NOESCAPE = 0x01;
     public final static int FNM_PATHNAME = 0x02;
     public final static int FNM_DOTMATCH = 0x04;
     public final static int FNM_CASEFOLD = 0x08;
 
     public final static int FNM_SYSCASE =  ?  : 0;
 
     public final static int FNM_NOMATCH = 1;
     public final static int FNM_ERROR   = 2;
 
     public final static byte[] EMPTY = new byte[0];
     public final static byte[] SLASH = new byte[]{'/'};
     public final static byte[] STAR = new byte[]{'*'};
     public final static byte[] DOUBLE_STAR = new byte[]{'*','*'};
 
     private static boolean isdirsep(byte c) {
         return c == '/' ||  && c == '\\';
     }
 
     private static int rb_path_next(byte[] _sint sint send) {
         while(s < send && !isdirsep(_s[s])) {
             s++;
         }
         return s;
     }
 
     private static int fnmatch_helper(byte[] bytesint pstartint pendbyte[] stringint sstartint sendint flags) {
         char test;
         int s = sstart;
         int pat = pstart;
         boolean escape = (flags & ) == 0;
         boolean pathname = (flags & ) != 0;
         boolean period = (flags & ) == 0;
         boolean nocase = (flags & ) != 0;
 
         while(pat<pend) {
             byte c = bytes[pat++];
             switch(c) {
             case '?':
                 if(s >= send || (pathname && isdirsep(string[s])) || 
                    (period && string[s] == '.' && (s == 0 || (pathname && isdirsep(string[s-1]))))) {
                     return ;
                 }
                 s++;
                 break;
            case '*':
                while(pat < pend && (c = bytes[pat++]) == '*') {}
                if(s < send && (period && string[s] == '.' && (s == 0 || (pathname && isdirsep(string[s-1]))))) {
                    return ;
                }
                if(pat > pend || (pat == pend && c == '*')) {
                    if(pathname && rb_path_next(stringssend) < send) {
                        return ;
                    } else {
                        return 0;
                    }
                } else if((pathname && isdirsep(c))) {
                    s = rb_path_next(stringssend);
                    if(s < send) {
                        s++;
                        break;
                    }
                    return ;
                }
                test = (char)((escape && c == '\\' && pat < pend ? bytes[pat] : c)&0xFF);
                test = Character.toLowerCase(test);
                pat--;
                while(s < send) {
                    if((c == '?' || c == '[' || Character.toLowerCase((charstring[s]) == test) &&
                       fnmatch(bytespatpendstringssendflags | ) == 0) {
                        return 0;
                    } else if((pathname && isdirsep(string[s]))) {
                        break;
                    }
                    s++;
                }
                return ;
            case '[':
                if(s >= send || (pathname && isdirsep(string[s]) || 
                                 (period && string[s] == '.' && (s == 0 || (pathname && isdirsep(string[s-1])))))) {
                    return ;
                }
                pat = range(bytespatpend, (char)(string[s]&0xFF), flags);
                if(pat == -1) {
                    return ;
                }
                s++;
                break;
            case '\\':
                if (escape) {
                    if (pat >= pend) {
                        c = '\\';
                    } else {
                        c = bytes[pat++];
                    }
                }
            default:
                if(s >= send) {
                    return ;
                }
                if( && (pathname && isdirsep(c) && isdirsep(string[s]))) {
                } else {
                    if (nocase) {
                        if(Character.toLowerCase((char)c) != Character.toLowerCase((char)string[s])) {
                            return ;
                        }
                        
                    } else {
                        if(c != (char)string[s]) {
                            return ;
                        }
                    }
                    
                }
                s++;
                break;
            }
        }
        return s >= send ? 0 : ;
    }
    public static int fnmatch(
            byte[] bytesint pstartint pend,
            byte[] stringint sstartint sendint flags) {
        
        // This method handles '**/' patterns and delegates to
        // fnmatch_helper for the main work.
        boolean period = (flags & ) == 0;
        boolean pathname = (flags & ) != 0;
        int pat_pos = pstart;
        int str_pos = sstart;
        int ptmp = -1;
        int stmp = -1;
        if (pathname) {
            while (true) {
                if (isDoubleStarAndSlash(bytespat_pos)) {
                    do { pat_pos += 3; } while (isDoubleStarAndSlash(bytespat_pos));
                    ptmp = pat_pos;
                    stmp = str_pos;
                }
                int patSlashIdx = nextSlashIndex(bytespat_pospend);
                int strSlashIdx = nextSlashIndex(stringstr_possend);
                if (fnmatch_helper(bytespat_pospatSlashIdx,
                        stringstr_posstrSlashIdxflags) == 0) {
                    if (patSlashIdx < pend && strSlashIdx < send) {
                        pat_pos = ++patSlashIdx;
                        str_pos = ++strSlashIdx;
                        continue;
                    }
                    if (patSlashIdx == pend && strSlashIdx == send) {
                        return 0;
                    }
                }
                /* failed : try next recursion */
                if (ptmp != -1 && stmp != -1 && !(period && string[stmp] == '.')) {
                    stmp = nextSlashIndex(stringstmpsend);
                    if (stmp < send) {
                        pat_pos = ptmp;
                        stmp++;
                        str_pos = stmp;
                        continue;
                    }
                }
                return ;
            }
        } else {
            return fnmatch_helper(bytespstartpendstringsstartsendflags);
        }
    }
    // are we at '**/'
    private static boolean isDoubleStarAndSlash(byte[] bytesint pos) {
        if ((bytes.length - pos) <= 2) {
            return false// not enough bytes
        }
        return bytes[pos] == '*'
            && bytes[pos + 1] == '*'
            && bytes[pos + 2] == '/';
    }
    // Look for slash, starting from 'start' position, until 'end'.
    private static int nextSlashIndex(byte[] bytesint startint end) {
        int idx = start;
        while (idx < end && idx < bytes.length && bytes[idx] != '/') {
            idx++;
        }
        return idx;
    }
    public static int range(byte[] _patint patint pendchar testint flags) {
        boolean not;
        boolean ok = false;
        boolean nocase = (flags & ) != 0;
        boolean escape = (flags & ) == 0;
        not = _pat[pat] == '!' || _pat[pat] == '^';
        if(not) {
            pat++;
        }
        if (nocase) {
            test = Character.toLowerCase(test);
        }
        while(_pat[pat] != ']') {
            char cstartcend;
            if(escape && _pat[pat] == '\\') {
                pat++;
            }
            if(pat >= pend) {
                return -1;
            }
            cstart = cend = (char)(_pat[pat++]&0xFF);
            if(_pat[pat] == '-' && _pat[pat+1] != ']') {
                pat++;
                if(escape && _pat[pat] == '\\') {
                    pat++;
                }
                if(pat >= pend) {
                    return -1;
                }
                cend = (char)(_pat[pat++] & 0xFF);
            }
            if (nocase) {
                if (Character.toLowerCase(cstart) <= test
                        && test <= Character.toLowerCase(cend)) {
                    ok = true;
                }
            } else {
                if (cstart <= test && test <= cend) {
                    ok = true;
                }
            }
        }
        return ok == not ? -1 : pat + 1;
    }
    public static List<ByteListpush_glob(String cwdByteList globByteListint flags) {
        List<ByteListresult = new ArrayList<ByteList>();
        if (globByteList.length() > 0) {
            push_braces(cwdresultnew GlobPattern(globByteListflags));
        }
        return result;
    }
    
    private static class GlobPattern {
        final byte[] bytes;        
        final int begin;
        final int end;
        
        int flags;
        int index;
        public GlobPattern(ByteList bytelistint flags) {
            this(bytelist.getUnsafeBytes(), bytelist.getBegin(),  bytelist.getBegin() + bytelist.getRealSize(), flags);
        }
        
        public GlobPattern(byte[] bytesint indexint endint flags) {
            this. = bytes;
            this. = index;
            this. = index;
            this. = end;
            this. = flags;
        }
        
        public int findClosingIndexOf(int leftTokenIndex) {
            if (leftTokenIndex == -1 || leftTokenIndex > return -1;
            
            byte leftToken = [leftTokenIndex];
            byte rightToken;
            
            switch (leftToken) {
            case '{'rightToken = '}'break;
            case '['rightToken = ']'break;
            defaultreturn -1;
            }
            
            int nest = 1; // leftToken made us start as nest 1
             = leftTokenIndex + 1;
            while (hasNext()) {
                byte c = next();
                
                if (c == leftToken) {
                    nest++;
                } else if (c == rightToken && --nest == 0) {
                    return index();
                }
            }
            
            return -1;
        }
        
        public boolean hasNext() {
            return  < ;
        }
        
        public void reset() {
             = ;
        }
        
        public void setIndex(int value) {
             = value;
        }
        
        // Get index of last read byte
        public int index() {
            return  - 1;
        }
        
        public int indexOf(byte c) {
            while (hasNext()) if (next() == creturn index();
            
            return -1;
        }
        
        public byte next() {
            return [++];
        }
    }
    public static interface GlobFunc {
        int call(byte[] ptrint pint lenObject ary);
    }
    private static class GlobArgs {
        GlobFunc func;
        int c = -1;
        List<ByteListv;
        
        public GlobArgs(GlobFunc funcList<ByteListarg) {
            this. = func;
            this. = arg;
        }
    }
    public final static GlobFunc push_pattern = new GlobFunc() {
            @SuppressWarnings("unchecked")
            public int call(byte[] ptrint pint lenObject ary) {
                ((Listary).add(new ByteList(ptrplen));
                return 0;
            }
        };
    public final static GlobFunc glob_caller = new GlobFunc() {
        public int call(byte[] ptrint pint lenObject ary) {
            GlobArgs args = (GlobArgs)ary;
            args.c = p;
            return args.func.call(ptrargs.clenargs.v);
        }
    };
    /*
     * Process {}'s (example: Dir.glob("{jruby,jython}/README*") 
     */
    private static int push_braces(String cwdList<ByteListresultGlobPattern pattern) {
        pattern.reset();
        int lbrace = pattern.indexOf((byte'{'); // index of left-most brace
        int rbrace = pattern.findClosingIndexOf(lbrace);// index of right-most brace
        // No, mismatched or escaped braces..Move along..nothing to see here
        if (lbrace == -1 || rbrace == -1 || 
                lbrace > 0 && pattern.bytes[lbrace-1] == '\\' || 
                rbrace > 0 && pattern.bytes[rbrace-1] == '\\') {
            ByteList unescaped = new ByteList(pattern.bytes.length-1);
            for (int i = pattern.begini < pattern.endi++) {
                byte b = pattern.bytes[i];
                if (b == '\\' && i < pattern.bytes.length - 1) {
                    byte next_b = pattern.bytes[i + 1];
                    if (next_b != '{' && next_b != '}') {
                        unescaped.append(b);
                    }
                } else {
                    unescaped.append(b);
                }
            }
            return push_globs(cwdresultunescaped.getUnsafeBytes(), unescaped.begin(), unescaped.length(), pattern.flags);
        }
        // Peel onion...make subpatterns out of outer layer of glob and recall with each subpattern 
        // Example: foo{a{c},b}bar -> fooa{c}bar, foobbar
        ByteList buf = new ByteList(20);
        int middleRegionIndex;
        int i = lbrace;
        while (pattern.bytes[i] != '}') {
            middleRegionIndex = i + 1;
            for(i = middleRegionIndexi < pattern.end && pattern.bytes[i] != '}' && pattern.bytes[i] != ','i++) {
                if (pattern.bytes[i] == '{'i = pattern.findClosingIndexOf(i); // skip inner braces
            }
            buf.length(0);
            buf.append(pattern.bytespattern.beginlbrace - pattern.begin);
            buf.append(pattern.bytesmiddleRegionIndexi - middleRegionIndex);
            buf.append(pattern.bytesrbrace + 1, pattern.end - (rbrace + 1));
            int status = push_braces(cwdresultnew GlobPattern(buf.getUnsafeBytes(), buf.getBegin(), buf.getRealSize(),pattern.flags));
            if(status != 0) return status;
        }
        
        return 0; // All braces pushed..
    }
    private static int push_globs(String cwdList<ByteListarybyte[] patternint pbeginint pendint pflags) {
        pflags |= ;
        return glob_helper(cwdpatternpbeginpend, -1, pflagsnew GlobArgs(ary));
    }
    private static boolean has_magic(byte[] bytesint beginint endint flags) {
        boolean escape = (flags & ) == 0;
        boolean nocase = (flags & ) != 0;
        int open = 0;
        for (int i = begini < endi++) {
            switch(bytes[i]) {
            case '?':
            case '*':
                return true;
            case '[':	/* Only accept an open brace if there is a close */
                open++;	/* brace to match it.  Bracket expressions must be */
                continue;	/* complete, according to Posix.2 */
            case ']':
                if (open > 0) return true;
                continue;
            case '\\':
                if (escape && i == endreturn false;
                break;
            default:
                if ( == 0 && nocase && Character.isLetter((char)(bytes[i]&0xFF))) return true;
            }
        }
        return false;
    }
    private static int remove_backslashes(byte[] bytesint indexint len) {
        int t = index;
        
        for (; index < lenindex++, t++) {
            if (bytes[index] == '\\' && ++index == lenbreak;
            
            bytes[t] = bytes[index];
        }
        
        return t;
    }
    private static int strchr(byte[] bytesint beginint endbyte ch) {
        for (int i = begini < endi++) {
            if (bytes[i] == chreturn i;
        }
        
        return -1;
    }
    private static byte[] extract_path(byte[] bytesint beginint end) {
        int len = end - begin;
        
        if (len > 1 && bytes[end-1] == '/' && (! || (len < 2 || bytes[end-2] != ':'))) len--;
        byte[] alloc = new byte[len];
        System.arraycopy(bytes,begin,alloc,0,len);
        return alloc;
    }
    private static byte[] extract_elem(byte[] bytesint beginint end) {
        int elementEnd = strchr(bytesbeginend, (byte)'/');
        if (elementEnd == -1) elementEnd = end;
        
        return extract_path(bytesbeginelementEnd);
    }
    
    // Win drive letter X:/
    private static boolean beginsWithDriveLetter(byte[] pathint beginint end) {
        return  && begin + 2 < end && path[begin + 1] == ':' && isdirsep(path[begin + 2]); 
    }
    // Is this nothing or literally root directory for the OS.
    private static boolean isRoot(byte[] base) {
        int length = base.length;
        
        return length == 0 ||  // empty
               length == 1 && isdirsep(base[0]) || // Just '/'
               length == 3 && beginsWithDriveLetter(base, 0, length); // Just X:/ 
    }
    
    private static boolean isJarFilePath(byte[] bytesint beginint end) {
        return end > 6 && bytes[begin] == 'f' && bytes[begin+1] == 'i' &&
            bytes[begin+2] == 'l' && bytes[begin+3] == 'e' && bytes[begin+4] == ':';
    }
    
    private static boolean isAbsolutePath(byte[] pathint beginint length) {
        return isdirsep(path[begin]) || beginsWithDriveLetter(pathbeginlength);
    }
    private static String[] files(File directory) {
        String[] files = directory.list();
        
        if (files != null) {
            String[] filesPlusDotFiles = new String[files.length + 2];
            System.arraycopy(files, 0, filesPlusDotFiles, 2, files.length);
            filesPlusDotFiles[0] = ".";
            filesPlusDotFiles[1] = "..";
            return filesPlusDotFiles;
        } else {
            return new String[0];
        }
    }
    private static final class DirGlobber {
        public final ByteList link;
        public final JarEntry jarEntry;
        public DirGlobber(ByteList linkJarEntry jarEntry) {
            this. = link;
            this. = jarEntry;
        }
    }
    private static boolean isSpecialFile(String name) {
        int length = name.length();
        
        if (length < 1 || length > 3 || name.charAt(0) != '.'return false;
        if (length == 1) return true;
        char c = name.charAt(1);
        if (length == 2 && (c == '.' || c == '/')) return true;
        return c == '.' && name.charAt(2) == '/';
    }
    private static int addToResultIfExists(String cwdbyte[] bytesint beginint endint flagsGlobFunc funcGlobArgs arg) {
        String fileName = newStringFromUTF8(bytesbeginend - begin);
        JavaSecuredFile file = cwd != null ? new JavaSecuredFile(cwdfileName) :
            new JavaSecuredFile(fileName);
        if (file.exists()) {
            boolean trailingSlash = bytes[end - 1] == '/';
            // On case-insenstive file systems any case string will 'exists',
            // but what does it display as if you ls/dir it?
            if ((flags & ) != 0 && !isSpecialFile(fileName)) {
                try {
                    String realName = file.getCanonicalFile().getName();
                    // TODO: This is only being done to the name of the file,
                    // but it should do for all parent directories too...
                    // TODO: OMGZ is this ugly
                    int fileNameLength = fileName.length();
                    int newEnd = fileNameLength <= 1 ? -1 : fileName.lastIndexOf('/'fileNameLength - 2);
                    if (newEnd != -1) {
                        realName = fileName.substring(0, newEnd + 1) + realName;
                    }
                    // It came in with a trailing slash preserve that in new name.
                    if (trailingSlashrealName = realName + "/";
                    bytes = realName.getBytes();
                    begin = 0;
                    end = bytes.length;
                } catch (Exception e) {} // Failure will just use what we pass in
            }
            
            return func.call(bytesbeginend - beginarg);
        }
        return 0;
    }
    private static ZipEntry getZipEntryFor(byte[] bytesint beginint end) {
        int ix = end;
        for (int i = 0; i < endi++) {
            if (bytes[begin + i] == '!') {
                ix = i;
                break;
            }
        }
        if (ix == endreturn null;
        String fileName = newStringFromUTF8(bytesbegin + 5, ix - 5);
        String entryName = newStringFromUTF8(bytesbegin + ix + 1, end - (ix + 1));
        if (entryName.startsWith("/")) entryName = entryName.substring(1);
        try {
            return RubyFile.getDirOrFileEntry(fileNameentryName);
        } catch (Exception e) {}
        
        return null;
    }
    private static int glob_helper(String cwdbyte[] bytesint beginint endint subint flagsGlobFunc funcGlobArgs arg) {
        int p,m;
        int status = 0;
        byte[] newpath = null;
        File st;
        p = sub != -1 ? sub : begin;
        if (!has_magic(bytespendflags)) {
            if ( || (flags & ) == 0) {
                newpath = new byte[end];
                System.arraycopy(bytes,0,newpath,0,end);
                if (sub != -1) {
                    p = (sub - begin);
                    end = remove_backslashes(newpathpend);
                    sub = p;
                } else {
                    end = remove_backslashes(newpath, 0, end);
                    bytes = newpath;
                }
            }
            if (isAbsolutePath(bytesbeginend)) {
                status = addToResultIfExists(nullbytesbeginendflagsfuncarg);
            } else if (isJarFilePath(bytesbeginend)) {
                if (getZipEntryFor(bytesbeginend) != null) {
                    status = func.call(bytesbeginendarg);
                }
            } else if ((end - begin) > 0) { // Length check is a hack.  We should not be reeiving "" as a filename ever.
                status = addToResultIfExists(cwdbytesbeginendflagsfuncarg);
            }
            return status;
        }
        
        ByteList buf = new ByteList(20);
        List<DirGlobberlink = new ArrayList<DirGlobber>();
        mainLoop: while(p != -1 && status == 0) {
            if (bytes[p] == '/'p++;
            m = strchr(bytespend, (byte)'/');
            if(has_magic(bytespm == -1 ? end : mflags)) {
                finalize: do {
                    byte[] base = extract_path(bytesbeginp);
                    byte[] dir = begin == p ? new byte[]{'.'} : base
                    byte[] magic = extract_elem(bytes,p,end);
                    boolean recursive = false;
                    String jar = null;
                    JarFile jf = null;
                    if(isAbsolutePath(dir, 0, dir.length)) {
                        st = new JavaSecuredFile(newStringFromUTF8(dir));
                    } else if(isJarFilePath(dir, 0, dir.length)) {
                        int ix = dir.length;
                        for(int i = 0;i<dir.length;i++) {
                            if(dir[i] == '!') {
                                ix = i;
                                break;
                            }
                        }
                        st = new JavaSecuredFile(newStringFromUTF8(dir, 5, ix-5));
                        if(ix<dir.length) {
                            jar = newStringFromUTF8(dirix+1, dir.length-(ix+1));
                            try {
                                jf = new JarFile(st);
                                if (jar.startsWith("/")) jar = jar.substring(1);
                                if (jf.getEntry(jar + "/") != nulljar = jar + "/";
                            } catch(Exception e) {
                                jar = null;
                                jf = null;
                            }
                        }
                    } else {
                        st = new JavaSecuredFile(cwdnewStringFromUTF8(dir));
                    }
                    if((jf != null && ("".equals(jar) || (jf.getJarEntry(jar) != null &&
                            jf.getJarEntry(jar).isDirectory()))) || st.isDirectory()) {
                        if(m != -1 && Arrays.equals(magic)) {
                            int n = base.length;
                            recursive = true;
                            buf.length(0);
                            buf.append(base);
                            buf.append(bytes, (base.length > 0 ? m : m + 1), end - (base.length > 0 ? m : m + 1));
                            if (jf != null) {
                                buf = fixBytesForJarInUTF8(buf.getUnsafeBytes(), buf.getBegin(), buf.getRealSize());
                            }
                            status = glob_helper(cwdbuf.getUnsafeBytes(), buf.getBegin(), buf.getRealSize(), nflagsfuncarg);
                            if(status != 0) {
                                break finalize;
                            }
                        }
                    } else {
                        break mainLoop;
                    }
                    if(jar == null) {
                        String[] dirp = files(st);
                        for(int i=0;i<dirp.length;i++) {
                            if(recursive) {
                                byte[] bs = getBytesInUTF8(dirp[i]);
                                if (fnmatch(,0,1,bs,0,bs.length,flags) != 0) {
                                    continue;
                                }
                                buf.length(0);
                                buf.append(base);
                                buf.append(isRoot(base) ?  :  );
                                buf.append(getBytesInUTF8(dirp[i]));
                                if (isAbsolutePath(buf.getUnsafeBytes(), buf.getBegin(), buf.getRealSize())) {
                                    st = new JavaSecuredFile(newStringFromUTF8(buf.getUnsafeBytes(), buf.getBegin(), buf.getRealSize()));
                                } else {
                                    st = new JavaSecuredFile(cwdnewStringFromUTF8(buf.getUnsafeBytes(), buf.getBegin(), buf.getRealSize()));
                                }
                                if(st.isDirectory() && !".".equals(dirp[i]) && !"..".equals(dirp[i])) {
                                    int t = buf.getRealSize();
                                    buf.append();
                                    buf.append();
                                    buf.append(bytesmend - m);
                                    status = glob_helper(cwdbuf.getUnsafeBytes(), buf.getBegin(), buf.getRealSize(), tflagsfuncarg);
                                    if(status != 0) {
                                        break;
                                    }
                                }
                                continue;
                            }
                            byte[] bs = getBytesInUTF8(dirp[i]);
                            if(fnmatch(magic,0,magic.length,bs,0, bs.length,flags) == 0) {
                                buf.length(0);
                                buf.append(base);
                                buf.append(isRoot(base) ?  :  );
                                buf.append(getBytesInUTF8(dirp[i]));
                                if(m == -1) {
                                    status = func.call(buf.getUnsafeBytes(),0, buf.getRealSize(),arg);
                                    if(status != 0) {
                                        break;
                                    }
                                    continue;
                                }
                                link.add(new DirGlobber(bufnull));
                                buf = new ByteList(20);
                            }
                        }
                    } else {
                        try {
                            List<JarEntrydirp = new ArrayList<JarEntry>();
                            for(Enumeration<JarEntryeje = jf.entries(); eje.hasMoreElements(); ) {
                                JarEntry je = eje.nextElement();
                                String name = je.getName();
                                int ix = name.indexOf('/'jar.length());
                                if (ix == -1 || ix == name.length()-1) {
                                    if("/".equals(jar) || (name.startsWith(jar) && name.length()>jar.length())) {
                                        dirp.add(je);
                                    }
                                }
                            }
                            for(JarEntry je : dirp) {
                                String basename = (new File(je.getName())).getName();
                                byte[] bs = getBytesInUTF8(basename);
                                byte[] absoluteName = getBytesInUTF8(je.getName());
                                int len = bs.length;
                                int absoluteLen = absoluteName.length;
                                if(je.isDirectory()) {
                                    len--;
                                    absoluteLen--;
                                }
                                if(recursive) {
                                    if(fnmatch(,0,1,bs,0,len,flags) != 0) {
                                        continue;
                                    }
                                    buf.length(0);
                                    buf.append(base, 0, base.length - jar.length());
                                    buf.append(isRoot(base) ?  : );
                                    buf.append(absoluteName, 0, absoluteLen);
                                    if(je.isDirectory()) {
                                        int t = buf.getRealSize();
                                        buf.append();
                                        buf.append();
                                        buf.append(bytesmend - m);
                                        buf = fixBytesForJarInUTF8(buf.getUnsafeBytes(), buf.getBegin(), buf.getRealSize());
                                        status = glob_helper(cwdbuf.getUnsafeBytes(), buf.getBegin(), buf.getRealSize(), tflagsfuncarg);
                                        if(status != 0) {
                                            break;
                                        }
                                    }
                                    continue;
                                }
                                if(fnmatch(magic,0,magic.length,bs,0,len,flags) == 0) {
                                    buf.length(0);
                                    buf.append(base, 0, base.length - jar.length());
                                    buf.append(isRoot(base) ?  : );
                                    buf.append(absoluteName, 0, absoluteLen);
                                    buf = fixBytesForJarInUTF8(buf.getUnsafeBytes(), 0, buf.getRealSize());
                                    if(m == -1) {
                                        status = func.call(buf.getUnsafeBytes(),0, buf.getRealSize(),arg);
                                        if(status != 0) {
                                            break;
                                        }
                                        continue;
                                    }
                                    link.add(new DirGlobber(bufje));
                                    buf = new ByteList(20);
                                }
                            }
                        } catch(Exception e) {}
                    }
                } while(false);
                if (link.size() > 0) {
                    for (DirGlobber globber : link) {
                        ByteList b = globber.link;
                        if (status == 0) {
                            if(isAbsolutePath(b.getUnsafeBytes(), b.begin(), b.getRealSize())) {
                                st = new JavaSecuredFile(newStringFromUTF8(b.getUnsafeBytes(), 0, b.getRealSize()));
                            } else {
                                st = new JavaSecuredFile(cwdnewStringFromUTF8(b.getUnsafeBytes(), 0, b.getRealSize()));
                            }
                            if(st.isDirectory() || (globber.jarEntry != null && globber.jarEntry.isDirectory()) ) {
                                int len = b.getRealSize();
                                buf.length(0);
                                buf.append(b);
                                buf.append(bytesmend - m);
                                if (globber.jarEntry != null) {
                                    buf = fixBytesForJarInUTF8(buf.getUnsafeBytes(), 0, buf.getRealSize());
                                }
                                status = glob_helper(cwdbuf.getUnsafeBytes(),0, buf.getRealSize(),len,flags,func,arg);
                            }
                        }
                    }
                    break mainLoop;
                }
            }
            p = m;
        }
        return status;
    }
    private static ByteList fixBytesForJarInUTF8(byte[] bufint offsetint len) {
        String path = newStringFromUTF8(bufoffsetlen);
        path = path.replace(".jar/"".jar!");
        return new ByteList(path.getBytes());
    }
    private static byte[] getBytesInUTF8(String s) {
        return RubyEncoding.encodeUTF8(s);
    }
    private static String newStringFromUTF8(byte[] bufint offsetint len) {
        return RubyEncoding.decodeUTF8(bufoffsetlen);
    }
    private static String newStringFromUTF8(byte[] buf) {
        return RubyEncoding.decodeUTF8(buf);
    }
New to GrepCode? Check out our FAQ X