/* * libbrlapi - A library providing access to braille terminals for applications. * * Copyright (C) 2006-2021 by * Samuel Thibault * Sébastien Hinderer * * 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 . */ 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); } } } }