public Object getFileAsBytes(String name, OC out, boolean allowZip) {
   // ?? used by eval of "WRITE FILE"
   // will be full path name
   if (name == null) return null;
   String fullName = name;
   String[] subFileList = null;
   if (name.indexOf("|") >= 0) {
     subFileList = PT.split(name, "|");
     name = subFileList[0];
     allowZip = true;
   }
   Object t =
       getBufferedInputStreamOrErrorMessageFromName(name, fullName, false, false, null, false);
   if (t instanceof String) return "Error:" + t;
   try {
     BufferedInputStream bis = (BufferedInputStream) t;
     Object bytes =
         (out != null
                 || !allowZip
                 || subFileList == null
                 || subFileList.length <= 1
                 || !JmolBinary.isZipS(bis) && !JmolBinary.isPngZipStream(bis)
             ? JmolBinary.getStreamAsBytes(bis, out)
             : JmolBinary.getZipFileContentsAsBytes(bis, subFileList, 1));
     bis.close();
     return bytes;
   } catch (Exception ioe) {
     return ioe.toString();
   }
 }
 Object createAtomSetCollectionFromString(
     String strModel, Map<String, Object> htParams, boolean isAppend) {
   setLoadState(htParams);
   boolean isAddH = (strModel.indexOf(JC.ADD_HYDROGEN_TITLE) >= 0);
   String[] fnames = (isAddH ? getFileInfo() : null);
   FileReader fileReader =
       new FileReader(
           this,
           viewer,
           "string",
           "string",
           "string",
           null,
           JmolBinary.getBR(strModel),
           htParams,
           isAppend);
   fileReader.run();
   if (fnames != null) setFileInfo(fnames);
   if (!isAppend && !(fileReader.getAtomSetCollection() instanceof String)) {
     viewer.zap(false, true, false);
     setFileInfo(
         new String[] {strModel == JC.MODELKIT_ZAP_STRING ? JC.MODELKIT_ZAP_TITLE : "string"});
   }
   return fileReader.getAtomSetCollection();
 }
 @Override
 public String postByteArray(String fileName, byte[] bytes) {
   Object ret =
       getBufferedInputStreamOrErrorMessageFromName(fileName, null, false, false, bytes, false);
   if (ret instanceof String) return (String) ret;
   try {
     ret = JmolBinary.getStreamAsBytes((BufferedInputStream) ret, null);
   } catch (IOException e) {
     try {
       ((BufferedInputStream) ret).close();
     } catch (IOException e1) {
       // ignore
     }
   }
   return (ret == null ? "" : JmolBinary.fixUTF((byte[]) ret));
 }
 public void clearPngjCache(String fileName) {
   if (fileName != null
       && (pngjCache == null
           || !pngjCache.containsKey(getCanonicalName(JmolBinary.getZipRoot(fileName))))) return;
   pngjCache = null;
   Logger.info("PNGJ cache cleared");
 }
 /**
  * Sets all local file references in a script file to point to files within dataPath. If a file
  * reference contains dataPath, then the file reference is left with that RELATIVE path.
  * Otherwise, it is changed to a relative file name within that dataPath.
  *
  * <p>Only file references starting with "file://" are changed.
  *
  * @param script
  * @param dataPath
  * @param isLocal
  * @return revised script
  */
 private static String setScriptFileRefs(String script, String dataPath, boolean isLocal) {
   if (dataPath == null) return script;
   boolean noPath = (dataPath.length() == 0);
   List<String> fileNames = new List<String>();
   JmolBinary.getFileReferences(script, fileNames);
   List<String> oldFileNames = new List<String>();
   List<String> newFileNames = new List<String>();
   int nFiles = fileNames.size();
   for (int iFile = 0; iFile < nFiles; iFile++) {
     String name0 = fileNames.get(iFile);
     String name = name0;
     if (isLocal == isLocal(name)) {
       int pt = (noPath ? -1 : name.indexOf("/" + dataPath + "/"));
       if (pt >= 0) {
         name = name.substring(pt + 1);
       } else {
         pt = name.lastIndexOf("/");
         if (pt < 0 && !noPath) name = "/" + name;
         if (pt < 0 || noPath) pt++;
         name = dataPath + name.substring(pt);
       }
     }
     Logger.info("FileManager substituting " + name0 + " --> " + name);
     oldFileNames.addLast("\"" + name0 + "\"");
     newFileNames.addLast("\1\"" + name + "\"");
   }
   return Txt.replaceStrings(script, oldFileNames, newFileNames);
 }
 void cachePut(String key, Object data) {
   key = key.replace('\\', '/');
   if (Logger.debugging) Logger.debug("cachePut " + key);
   if (data == null || "".equals(data)) { // J2S error -- cannot implement Int32Array.equals
     cache.remove(key);
     return;
   }
   cache.put(key, data);
   JmolBinary.getCachedPngjBytes(this, key);
 }
 /**
  * just check for a file as being readable. Do not go into a zip file
  *
  * @param filename
  * @return String[2] where [0] is fullpathname and [1] is error message or null
  */
 String[] getFullPathNameOrError(String filename) {
   String[] names = classifyName(filename, true);
   if (names == null || names[0] == null || names.length < 2)
     return new String[] {null, "cannot read file name: " + filename};
   String name = names[0];
   String fullPath = names[0].replace('\\', '/');
   name = JmolBinary.getZipRoot(name);
   Object errMsg =
       getBufferedInputStreamOrErrorMessageFromName(name, fullPath, false, true, null, false);
   return new String[] {fullPath, (errMsg instanceof String ? (String) errMsg : null)};
 }
 public String getEmbeddedFileState(String fileName) {
   String[] dir = null;
   dir = getZipDirectory(fileName, false);
   if (dir.length == 0) {
     String state = viewer.getFileAsString4(fileName, -1, false, true, false);
     return (state.indexOf(JC.EMBEDDED_SCRIPT_TAG) < 0 ? "" : JmolBinary.getEmbeddedScript(state));
   }
   for (int i = 0; i < dir.length; i++)
     if (dir[i].indexOf(".spt") >= 0) {
       String[] data = new String[] {fileName + "|" + dir[i], null};
       getFileDataOrErrorAsString(data, -1, false, false, false);
       return data[1];
     }
   return "";
 }
 Object getBufferedReaderOrErrorMessageFromName(
     String name, String[] fullPathNameReturn, boolean isBinary, boolean doSpecialLoad) {
   Object data = cacheGet(name, false);
   boolean isBytes = PT.isAB(data);
   byte[] bytes = (isBytes ? (byte[]) data : null);
   if (name.startsWith("cache://")) {
     if (data == null) return "cannot read " + name;
     if (isBytes) {
       bytes = (byte[]) data;
     } else {
       return JmolBinary.getBR((String) data);
     }
   }
   String[] names = classifyName(name, true);
   if (names == null) return "cannot read file name: " + name;
   if (fullPathNameReturn != null) fullPathNameReturn[0] = names[0].replace('\\', '/');
   return getUnzippedReaderOrStreamFromName(
       names[0], bytes, false, isBinary, false, doSpecialLoad, null);
 }
 /**
  * @param data [0] initially path name, but returned as full path name; [1]file contents
  *     (directory listing for a ZIP/JAR file) or error string
  * @param nBytesMax or -1
  * @param doSpecialLoad
  * @param allowBinary
  * @param checkProtected TODO
  * @return true if successful; false on error
  */
 boolean getFileDataOrErrorAsString(
     String[] data,
     int nBytesMax,
     boolean doSpecialLoad,
     boolean allowBinary,
     boolean checkProtected) {
   data[1] = "";
   String name = data[0];
   if (name == null) return false;
   Object t = getBufferedReaderOrErrorMessageFromName(name, data, false, doSpecialLoad);
   if (t instanceof String) {
     data[1] = (String) t;
     return false;
   }
   if (checkProtected && !checkSecurity(data[0])) {
     data[1] = "java.io. Security exception: cannot read file " + data[0];
     return false;
   }
   try {
     return JmolBinary.readAll((BufferedReader) t, nBytesMax, allowBinary, data, 1);
   } catch (Exception e) {
     return false;
   }
 }
 /**
  * @param fileName
  * @param addManifest
  * @return [] if not a zip file;
  */
 public String[] getZipDirectory(String fileName, boolean addManifest) {
   Object t =
       getBufferedInputStreamOrErrorMessageFromName(fileName, fileName, false, false, null, false);
   return JmolBinary.getZipDirectoryAndClose((BufferedInputStream) t, addManifest);
 }
 /**
  * delivers file contents and directory listing for a ZIP/JAR file into sb
  *
  * @param name
  * @param header
  * @param fileData
  * @return name of entry
  */
 private String getObjectAsSections(String name, String header, Map<String, String> fileData) {
   if (name == null) return null;
   String[] subFileList = null;
   boolean asBinaryString = false;
   String name0 = name.replace('\\', '/');
   if (name.indexOf(":asBinaryString") >= 0) {
     asBinaryString = true;
     name = name.substring(0, name.indexOf(":asBinaryString"));
   }
   SB sb = null;
   if (fileData.containsKey(name0)) return name0;
   if (name.indexOf("#JMOL_MODEL ") >= 0) {
     fileData.put(name0, name0 + "\n");
     return name0;
   }
   String fullName = name;
   if (name.indexOf("|") >= 0) {
     subFileList = PT.split(name, "|");
     name = subFileList[0];
   }
   BufferedInputStream bis = null;
   try {
     Object t =
         getBufferedInputStreamOrErrorMessageFromName(name, fullName, false, false, null, false);
     if (t instanceof String) {
       fileData.put(name0, (String) t + "\n");
       return name0;
     }
     bis = (BufferedInputStream) t;
     if (JmolBinary.isCompoundDocumentS(bis)) {
       JmolDocument doc = (JmolDocument) Interface.getOptionInterface("io2.CompoundDocument");
       doc.setStream(bis, true);
       doc.getAllDataMapped(name.replace('\\', '/'), "Molecule", fileData);
     } else if (JmolBinary.isZipS(bis)) {
       JmolBinary.getAllZipData(bis, subFileList, name.replace('\\', '/'), "Molecule", fileData);
     } else if (asBinaryString) {
       // used for Spartan binary file reading
       JmolDocument bd = (JmolDocument) Interface.getOptionInterface("io2.BinaryDocument");
       bd.setStream(bis, false);
       sb = new SB();
       // note -- these headers must match those in ZipUtil.getAllData and
       // CompoundDocument.getAllData
       if (header != null) sb.append("BEGIN Directory Entry " + name0 + "\n");
       try {
         while (true) sb.append(Integer.toHexString(bd.readByte() & 0xFF)).appendC(' ');
       } catch (Exception e1) {
         sb.appendC('\n');
       }
       if (header != null) sb.append("\nEND Directory Entry " + name0 + "\n");
       fileData.put(name0, sb.toString());
     } else {
       BufferedReader br =
           JmolBinary.getBufferedReader(
               JmolBinary.isGzipS(bis)
                   ? new BufferedInputStream(JmolBinary.newGZIPInputStream(bis))
                   : bis,
               null);
       String line;
       sb = new SB();
       if (header != null) sb.append("BEGIN Directory Entry " + name0 + "\n");
       while ((line = br.readLine()) != null) {
         sb.append(line);
         sb.appendC('\n');
       }
       br.close();
       if (header != null) sb.append("\nEND Directory Entry " + name0 + "\n");
       fileData.put(name0, sb.toString());
     }
   } catch (Exception ioe) {
     fileData.put(name0, ioe.toString());
   }
   if (bis != null)
     try {
       bis.close();
     } catch (Exception e) {
       //
     }
   if (!fileData.containsKey(name0)) fileData.put(name0, "FILE NOT FOUND: " + name0 + "\n");
   return name0;
 }
  public Object getUnzippedReaderOrStreamFromName(
      String name,
      byte[] bytes,
      boolean allowZipStream,
      boolean forceInputStream,
      boolean isTypeCheckOnly,
      boolean doSpecialLoad,
      Map<String, Object> htParams) {
    String[] subFileList = null;
    String[] info = (bytes == null && doSpecialLoad ? getSpartanFileList(name) : null);
    String name00 = name;
    if (info != null) {
      if (isTypeCheckOnly) return info;
      if (info[2] != null) {
        String header = info[1];
        Map<String, String> fileData = new Hashtable<String, String>();
        if (info.length == 3) {
          // we need information from the output file, info[2]
          String name0 = getObjectAsSections(info[2], header, fileData);
          fileData.put("OUTPUT", name0);
          info = JmolBinary.spartanFileList(name, fileData.get(name0));
          if (info.length == 3) {
            // might have a second option
            name0 = getObjectAsSections(info[2], header, fileData);
            fileData.put("OUTPUT", name0);
            info = JmolBinary.spartanFileList(info[1], fileData.get(name0));
          }
        }
        // load each file individually, but return files IN ORDER
        SB sb = new SB();
        if (fileData.get("OUTPUT") != null) sb.append(fileData.get(fileData.get("OUTPUT")));
        String s;
        for (int i = 2; i < info.length; i++) {
          name = info[i];
          name = getObjectAsSections(name, header, fileData);
          Logger.info("reading " + name);
          s = fileData.get(name);
          sb.append(s);
        }
        s = sb.toString();
        if (spardirCache == null) spardirCache = new Hashtable<String, byte[]>();
        spardirCache.put(name00.replace('\\', '/'), s.getBytes());
        return JmolBinary.getBR(s);
      }
      // continuing...
      // here, for example, for an SPT file load that is not just a type check
      // (type check is only for application file opening and drag-drop to
      // determine if
      // script or load command should be used)
    }

    if (bytes == null && pngjCache != null) {
      bytes = JmolBinary.getCachedPngjBytes(this, name);
      if (bytes != null && htParams != null) htParams.put("sourcePNGJ", Boolean.TRUE);
    }
    String fullName = name;
    if (name.indexOf("|") >= 0) {
      subFileList = PT.split(name, "|");
      if (bytes == null) Logger.info("FileManager opening 3 " + name);
      name = subFileList[0];
    }
    Object t =
        (bytes == null
            ? getBufferedInputStreamOrErrorMessageFromName(
                name, fullName, true, false, null, !forceInputStream)
            : JmolBinary.getBIS(bytes));
    try {
      if (t instanceof String) return t;
      if (t instanceof BufferedReader) return t;
      BufferedInputStream bis = JmolBinary.getUnzippedInputStream((BufferedInputStream) t);
      if (JmolBinary.isCompoundDocumentS(bis)) {
        JmolDocument doc = (JmolDocument) Interface.getOptionInterface("io2.CompoundDocument");
        doc.setStream(bis, true);
        return JmolBinary.getBR(doc.getAllDataFiles("Molecule", "Input").toString());
      }
      if (JmolBinary.isPickleS(bis)) return bis;
      bis = JmolBinary.checkPngZipStream(bis);
      if (JmolBinary.isZipS(bis)) {
        if (allowZipStream) return JmolBinary.newZipInputStream(bis);
        Object o = JmolBinary.getZipFileContents(bis, subFileList, 1, forceInputStream);
        return (o instanceof String ? JmolBinary.getBR((String) o) : o);
      }
      return (forceInputStream ? bis : JmolBinary.getBufferedReader(bis, null));
    } catch (Exception ioe) {
      return ioe.toString();
    }
  }
 public Object getBufferedInputStreamOrErrorMessageFromName(
     String name,
     String fullName,
     boolean showMsg,
     boolean checkOnly,
     byte[] outputBytes,
     boolean allowReader) {
   byte[] cacheBytes = null;
   if (outputBytes == null) {
     cacheBytes =
         (fullName == null || pngjCache == null
             ? null
             : JmolBinary.getCachedPngjBytes(this, fullName));
     if (cacheBytes == null) cacheBytes = (byte[]) cacheGet(name, true);
   }
   BufferedInputStream bis = null;
   Object ret = null;
   String errorMessage = null;
   try {
     if (cacheBytes == null) {
       boolean isPngjBinaryPost = (name.indexOf("?POST?_PNGJBIN_") >= 0);
       boolean isPngjPost = (isPngjBinaryPost || name.indexOf("?POST?_PNGJ_") >= 0);
       if (name.indexOf("?POST?_PNG_") > 0 || isPngjPost) {
         String[] errMsg = new String[1];
         byte[] bytes = viewer.getImageAsBytes(isPngjPost ? "PNGJ" : "PNG", 0, 0, -1, errMsg);
         if (errMsg[0] != null) return errMsg[0];
         if (isPngjBinaryPost) {
           outputBytes = bytes;
           name = PT.simpleReplace(name, "?_", "=_");
         } else {
           name = new SB().append(name).append("=").appendSB(Base64.getBase64(bytes)).toString();
         }
       }
       int iurl = urlTypeIndex(name);
       boolean isURL = (iurl >= 0);
       String post = null;
       if (isURL && (iurl = name.indexOf("?POST?")) >= 0) {
         post = name.substring(iurl + 6);
         name = name.substring(0, iurl);
       }
       boolean isApplet = (appletDocumentBaseURL != null);
       if (name.indexOf(".png") >= 0 && pngjCache == null && viewer.cachePngFiles())
         JmolBinary.cachePngjFile(this, null);
       if (isApplet || isURL) {
         if (isApplet && isURL && appletProxy != null)
           name = appletProxy + "?url=" + urlEncode(name);
         URL url =
             (isApplet
                 ? new URL(appletDocumentBaseURL, name, null)
                 : new URL((URL) null, name, null));
         if (checkOnly) return null;
         name = url.toString();
         if (showMsg && name.toLowerCase().indexOf("password") < 0)
           Logger.info("FileManager opening 1 " + name);
         ret = viewer.apiPlatform.getBufferedURLInputStream(url, outputBytes, post);
         byte[] bytes = null;
         if (ret instanceof SB) {
           SB sb = (SB) ret;
           if (allowReader && !JmolBinary.isBase64(sb)) return JmolBinary.getBR(sb.toString());
           bytes = JmolBinary.getBytesFromSB(sb);
         } else if (PT.isAB(ret)) {
           bytes = (byte[]) ret;
         }
         if (bytes != null) ret = JmolBinary.getBIS(bytes);
       } else if ((cacheBytes = (byte[]) cacheGet(name, true)) == null) {
         if (showMsg) Logger.info("FileManager opening 2 " + name);
         ret = viewer.apiPlatform.getBufferedFileInputStream(name);
       }
       if (ret instanceof String) return ret;
     }
     bis = (cacheBytes == null ? (BufferedInputStream) ret : JmolBinary.getBIS(cacheBytes));
     if (checkOnly) {
       bis.close();
       bis = null;
     }
     return bis;
   } catch (Exception e) {
     try {
       if (bis != null) bis.close();
     } catch (IOException e1) {
     }
     errorMessage = "" + e;
   }
   return errorMessage;
 }