blob: 7b66b4ce61c22b1da00c41a826bfa60b72724cff [file] [log] [blame] [edit]
/*
* libbrlapi - A library providing access to braille terminals for applications.
*
* Copyright (C) 2006-2023 by
* Samuel Thibault <Samuel.Thibault@ens-lyon.org>
* Sébastien Hinderer <Sebastien.Hinderer@ens-lyon.org>
*
* libbrlapi comes with ABSOLUTELY NO WARRANTY.
*
* This is free software, placed 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. Please see the file LICENSE-LGPL for details.
*
* Web Page: http://brltty.app/
*
* This software is maintained by Dave Mielke <dave@mielke.cc>.
*/
package org.a11y.brlapi;
import java.util.Arrays;
public class WriteArguments extends Component {
private String text = null;
private byte andMask[] = null;
private byte orMask[] = null;
private int regionBegin = 0;
private int regionSize = 0;
private int cursorPosition = Constants.CURSOR_LEAVE;
private int displayNumber = Constants.DISPLAY_DEFAULT;
public WriteArguments () {
}
public String getText () {
return text;
}
public WriteArguments setText (String text) {
this.text = text;
return this;
}
public byte[] getAndMask () {
return andMask;
}
public WriteArguments setAndMask (byte[] mask) {
andMask = mask;
return this;
}
public byte[] getOrMask () {
return orMask;
}
public WriteArguments setOrMask (byte[] mask) {
orMask = mask;
return this;
}
public int getRegionBegin () {
return regionBegin;
}
public WriteArguments setRegionBegin (int begin) {
regionBegin = begin;
return this;
}
public int getRegionSize () {
return regionSize;
}
public WriteArguments setRegionSize (int size) {
regionSize = size;
return this;
}
public WriteArguments setRegion (int begin, int size) {
setRegionBegin(begin);
setRegionSize(size);
return this;
}
public int getCursorPosition () {
return cursorPosition;
}
public WriteArguments setCursorPosition (int position) {
cursorPosition = position;
return this;
}
public int getDisplayNumber () {
return displayNumber;
}
public WriteArguments setDisplayNumber (int number) {
displayNumber = number;
return this;
}
public final static String TEXT = "text";
public final static String AND_MASK = "and-mask";
public final static String OR_MASK = "or-mask";
public final static String REGION_BEGIN = "region begin";
public final static String REGION_SIZE = "region size";
public final static String CURSOR_POSITION = "cursor position";
public final static String DISPLAY_NUMBER = "display number";
private static void checkRange (String description, int value, Integer minimum, Integer maximum) {
try {
if (minimum != null) Parse.checkMinimum(description, value, minimum);
if (maximum != null) Parse.checkMaximum(description, value, maximum);
} catch (SyntaxException exception) {
throw new IllegalStateException(exception.getMessage());
}
}
public final void check (int cellCount, boolean fix) {
boolean haveRegionBegin = regionBegin != 0;
boolean haveRegionSize = regionSize != 0;
boolean haveRegion = haveRegionBegin || haveRegionSize;
boolean haveText = text != null;
boolean haveAndMask = andMask != null;
boolean haveOrMask = orMask != null;
boolean haveContent = haveText || haveAndMask || haveOrMask;
if (haveRegion || haveContent) {
if (!haveContent) {
throw new IllegalStateException(
String.format(
"region content (%s, %s, and/or %s) not specified",
TEXT, AND_MASK, OR_MASK
)
);
}
if (!haveRegionBegin) {
if (!fix) {
throw new IllegalStateException(
String.format(
"%s not set", REGION_BEGIN
)
);
}
regionBegin = 1;
haveRegion = haveRegionBegin = true;
}
if (!haveRegionSize) {
if (!fix) {
throw new IllegalStateException(
String.format(
"%s not set", REGION_SIZE
)
);
}
regionSize = 0;
if (haveText) regionSize = Math.max(regionSize, text.length());
if (haveAndMask) regionSize = Math.max(regionSize, andMask.length);
if (haveOrMask) regionSize = Math.max(regionSize, orMask.length);
haveRegion = haveRegionSize = true;
}
checkRange(REGION_BEGIN, regionBegin, 1, cellCount);
checkRange(REGION_SIZE, regionSize, 1, null);
{
int maximum = cellCount + 1 - regionBegin;
if (!fix) {
checkRange(REGION_SIZE, regionSize, null, maximum);
} else if (regionSize > maximum) {
regionSize = maximum;
}
}
if (haveText) {
int textLength = text.length();
if (textLength > regionSize) {
if (!fix) {
throw new IllegalStateException(
String.format(
"%s length is greater than %s: %d > %d",
TEXT, REGION_SIZE,
textLength, regionSize
)
);
}
text = text.substring(0, regionSize);
} else if (textLength < regionSize) {
if (!fix) {
throw new IllegalStateException(
String.format(
"%s length is less than %s: %d < %d",
TEXT, REGION_SIZE,
textLength, regionSize
)
);
}
StringBuilder newText = new StringBuilder(text);
while (newText.length() < regionSize) newText.append(' ');
text = newText.toString();
}
}
if (haveAndMask) {
int andSize = andMask.length;
if (andSize > regionSize) {
if (!fix) {
throw new IllegalStateException(
String.format(
"%s size is greater than %s: %d > %d",
AND_MASK, REGION_SIZE,
andSize, regionSize
)
);
}
byte[] newMask = new byte[regionSize];
System.arraycopy(andMask, 0, newMask, 0, regionSize);
andMask = newMask;
} else if (andSize < regionSize) {
if (!fix) {
throw new IllegalStateException(
String.format(
"%s size is less than %s: %d < %d",
AND_MASK, REGION_SIZE,
andSize, regionSize
)
);
}
byte[] newMask = new byte[regionSize];
System.arraycopy(andMask, 0, newMask, 0, andSize);
Arrays.fill(newMask, andSize, (regionSize - andSize), (byte)BYTE_MASK);
andMask = newMask;
}
}
if (haveOrMask) {
int orSize = orMask.length;
if (orSize > regionSize) {
if (!fix) {
throw new IllegalStateException(
String.format(
"%s size is greater than %s: %d > %d",
OR_MASK, REGION_SIZE,
orSize, regionSize
)
);
}
byte[] newMask = new byte[regionSize];
System.arraycopy(orMask, 0, newMask, 0, regionSize);
orMask = newMask;
} else if (orSize < regionSize) {
if (!fix) {
throw new IllegalStateException(
String.format(
"%s size is less than %s: %d < %d",
OR_MASK, REGION_SIZE,
orSize, regionSize
)
);
}
byte[] newMask = new byte[regionSize];
System.arraycopy(orMask, 0, newMask, 0, orSize);
Arrays.fill(newMask, orSize, (regionSize - orSize), (byte)0);
orMask = newMask;
}
}
}
if (cursorPosition != Constants.CURSOR_OFF) {
if (cursorPosition != Constants.CURSOR_LEAVE) {
checkRange(CURSOR_POSITION, cursorPosition, 1, cellCount);
}
}
}
}