Skip to content

Commit

Permalink
Add encoding parameter to read and others.
Browse files Browse the repository at this point in the history
  • Loading branch information
LadyCailin committed Feb 12, 2021
1 parent 80f18e6 commit a955f1e
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 18 deletions.
20 changes: 17 additions & 3 deletions src/main/java/com/laytonsmith/PureUtilities/ZipReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -219,17 +219,31 @@ public InputStream getInputStream() throws FileNotFoundException, IOException {
}
}


/**
* If the file is a simple text file, this function is your best option. It returns the contents of the file as a
* string.
* If the file is a simple text file, this function is your best option.It returns the contents of the file as a
UTF-8 string.
*
* @return
* @throws FileNotFoundException If the file is not found
* @throws IOException If you specify a file that isn't a zip file as if it were a folder
*/
public String getFileContents() throws FileNotFoundException, IOException {
return getFileContents("UTF-8");
}

/**
* If the file is a simple text file, this function is your best option.It returns the contents of the file as a
string.
*
* @param charset
* @return
* @throws FileNotFoundException If the file is not found
* @throws IOException If you specify a file that isn't a zip file as if it were a folder
*/
public String getFileContents(String charset) throws FileNotFoundException, IOException {
if(!isZipped) {
return FileUtil.read(file);
return FileUtil.read(file, charset);
} else {
return StreamUtils.GetString(getInputStream());
}
Expand Down
51 changes: 36 additions & 15 deletions src/main/java/com/laytonsmith/core/functions/FileHandling.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.laytonsmith.annotations.api;
import com.laytonsmith.annotations.core;
import com.laytonsmith.annotations.noboilerplate;
import com.laytonsmith.core.ArgumentValidation;
import com.laytonsmith.core.MSLog;
import com.laytonsmith.core.MSVersion;
import com.laytonsmith.core.LogLevel;
Expand Down Expand Up @@ -64,8 +65,8 @@ public static String docs() {
@DocumentLink(0)
public static class read extends AbstractFunction implements DocumentLinkProvider {

public static String file_get_contents(String fileLocation) throws Exception {
return new ZipReader(new File(fileLocation)).getFileContents();
public static String file_get_contents(String fileLocation, String charset) throws Exception {
return new ZipReader(new File(fileLocation)).getFileContents(charset);
}

@Override
Expand All @@ -75,19 +76,23 @@ public String getName() {

@Override
public Integer[] numArgs() {
return new Integer[]{1};
return new Integer[]{1, 2};
}

@Override
public Mixed exec(Target t, Environment env, Mixed... args) throws CancelCommandException, ConfigRuntimeException {
File location = Static.GetFileFromArgument(args[0].val(), env, t, null);
String charset = "UTF-8";
if(args.length > 1) {
charset = ArgumentValidation.getString(args[1], t);
}
try {
// Verify this file is not above the craftbukkit directory (or whatever directory the user specified).
// Cmdline mode doesn't currently have this restriction.
if(!Static.InCmdLine(env, true) && !Security.CheckSecurity(location)) {
throw new CRESecurityException("You do not have permission to access the file '" + location + "'", t);
}
String s = file_get_contents(location.getAbsolutePath());
String s = file_get_contents(location.getAbsolutePath(), charset);
s = s.replace("\r\n", "\n");
return new CString(s, t);
} catch (Exception ex) {
Expand All @@ -100,10 +105,11 @@ public Mixed exec(Target t, Environment env, Mixed... args) throws CancelCommand

@Override
public String docs() {
return "string {file} Reads in a file from the file system at location var1 and returns it as a string. The path is relative to"
return "string {file, [encoding]} Reads in a file from the file system at location var1 and returns it as a string. The path is relative to"
+ " the file that is being run, not CommandHelper. If the file is not found, or otherwise can't be read in, an IOException is thrown."
+ " If the file specified is not within base-dir (as specified in the preferences file), a SecurityException is thrown."
+ " The line endings for the string returned will always be \\n, even if they originally were \\r\\n.";
+ " The line endings for the string returned will always be \\n, even if they originally were \\r\\n. Encoding defaults"
+ " to UTF-8 if not specified.";
}

@Override
Expand Down Expand Up @@ -165,15 +171,16 @@ public String getName() {

@Override
public Integer[] numArgs() {
return new Integer[]{1};
return new Integer[]{1, 2};
}

@Override
public String docs() {
return "string {path} Returns the value of a file at compile time only. Unlike read, this runs and is fully resolved"
return "string {path, [encoding]} Returns the value of a file at compile time only. Unlike read, this runs and is fully resolved"
+ " at compile time. This is useful for optimization reasons, if you have a file that is unchanging, this can be"
+ " used instead of read(), to prevent a runtime hit each time the code is executed. Otherwise, this method is"
+ " equivalent to read(). The path must be fully resolved at compile time.";
+ " equivalent to read(). The path must be fully resolved at compile time. Encoding is optional, and"
+ " defaults to UTF-8.";
}

@Override
Expand All @@ -195,7 +202,13 @@ public ParseTree optimizeDynamic(Target t, Environment env,
throw new ConfigCompileException(getName() + " can only accept hardcoded paths.", t);
}

String ret = new read().exec(t, env, children.get(0).getData()).val();
String ret;
if(children.size() == 1) {
ret = new read().exec(t, env, children.get(0).getData()).val();
} else {
ret = new read().exec(t, env, children.get(0).getData(),
children.get(1).getData()).val();
}
ParseTree tree = new ParseTree(new CString(ret, t), fileOptions);
return tree;
}
Expand Down Expand Up @@ -253,8 +266,16 @@ public Mixed exec(final Target t, final Environment environment, Mixed... args)
startup();
final String file = args[0].val();
final CClosure callback;
if(!(args[1].isInstanceOf(CClosure.TYPE))) {
throw new CRECastException("Expected parameter 2 of " + getName() + " to be a closure!", t);
int callbackIndex = 0;
String _encoding = "UTF-8";
if(args.length == 3) {
_encoding = ArgumentValidation.getString(args[1], t);
callbackIndex = 1;
}
final String encoding = _encoding;

if(!(args[1 + callbackIndex].isInstanceOf(CClosure.TYPE))) {
throw new CRECastException("Expected parameter " + (2 + callbackIndex) + " of " + getName() + " to be a closure!", t);
} else {
callback = ((CClosure) args[1]);
}
Expand Down Expand Up @@ -285,7 +306,7 @@ public void run() {
try {
//It's a local file read
File _file = Static.GetFileFromArgument(file, environment, t, null);
returnString = FileUtil.read(_file);
returnString = FileUtil.read(_file, encoding);
} catch (IOException ex) {
exception = new CREIOException(ex.getMessage(), t, ex);
}
Expand Down Expand Up @@ -322,12 +343,12 @@ public String getName() {

@Override
public Integer[] numArgs() {
return new Integer[]{2};
return new Integer[]{2, 3};
}

@Override
public String docs() {
return "void {file, callback} Asyncronously reads in a file. ---- "
return "void {file, [encoding], callback} Asyncronously reads in a file. ---- "
+ " This may be a remote file accessed with an SCP style path. (See the [[SCP|wiki article]]"
+ " about SCP credentials for more information.) If the file is not found, or otherwise can't be read in, an IOException is thrown."
+ " If the file specified is not within base-dir (as specified in the preferences file), a SecurityException is thrown."
Expand Down

0 comments on commit a955f1e

Please sign in to comment.