src.com.ibm.as400.access.NPDataAnalyzer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jt400-jdk8 Show documentation
Show all versions of jt400-jdk8 Show documentation
The Open Source version of the IBM Toolbox for Java
///////////////////////////////////////////////////////////////////////////////
//
// JTOpen (IBM Toolbox for Java - OSS version)
//
// Filename: NPDataAnalyzer.java
//
// The source code contained herein is licensed under the IBM Public License
// Version 1.0, which has been approved by the Open Source Initiative.
// Copyright (C) 1997-2000 International Business Machines Corporation and
// others. All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
package com.ibm.as400.access;
/**
* Class NPDataAnalyzer is an internal class used to analyze print data
* streams. It can detect if they are SCS or AFP and if they are not
* one of those it will default to USERASCII.
*
**/
public class NPDataAnalyzer extends Object
{
static final String copyright = "Copyright (C) 1997-2000 International Business Machines Corporation and others.";
private static final String DT_AFPDS = "*AFPDS";
private static final String DT_USERASCII = "*USERASCII";
private static final String DT_SCS = "*SCS";
private static boolean dataIsAFP(byte[] buf, int offset, int len)
{
boolean fRC = false, fDone = false;
int tempOffset = offset;
int tempLen;
while ((tempOffset < len) && !fDone)
{
if (buf[tempOffset] == 0x5A)
{
// we will say this is AFP if we see atleast 2 0x5As
if (tempOffset != offset)
{
fRC = true; // second or later 5A
}
// if we have atleast 3 bytes left
// jump ahead that many bytes
if ((len-tempOffset) >= 3)
{
// get the AFP structured field length from BigEndian
tempOffset++; // move to length field
// tempLen = xlate.getInt16(buf, tempOffset);
tempLen = BinaryConverter.byteArrayToUnsignedShort(buf, tempOffset);
tempOffset += tempLen;
if (tempLen < 5)
{
// can never be less than 5 for the
// length because the length itself is 2 bytes
// and then there is the 3 byte triplet.
fDone = true; // we are done here
fRC = false; // not AFP
}
} else {
fDone = true; // not enough data to process we are done
}
} else {
// not a 5A, NOT AFP and we are done
fRC = false;
fDone = true;
}
} // end while()
return fRC;
} // dataIsAFP()
private static boolean dataIsSCS(byte[] buf, int offset, int len)
{
boolean fRC = false;
boolean fDone = false;
while ((len > 0) &&
!fDone)
{
// cast next byte to an int and AND (&) it with 0xFF,
// because we want unsigned bytes and we do a less
// than operation with it (<) and don't want it to be
// negative ever.
int nextByte = (int)buf[offset] & 0x000000FF;
if (nextByte < (int)SPACE_CC)
{
switch(nextByte)
{
/**********************************************************
* Process all one byte SCS commands *
* I do not set the RC to YES here because one byte of these*
* doesnot make it SCS data. A case in point was where *
* the use sends 1K of 0x36 codepoints - should be a K of *
* ASCII "6" chars, but we say it is SCS and only contains *
* the 0x36 character, no writable data. *
* CASE backspace: *
* CASE expanded backspace: *
* CASE unitbackspace: *
* CASE bel: *
* CASE carriage return: *
* CASE form feed: *
* CASE required form feed: *
* CASE graphic escape: *
* CASE horizontal tab: *
* CASE indent tab: *
* CASE line feed: *
* CASE required new line: *
* CASE null: *
* CASE new line: *
* CASE interchange record separator: *
* CASE enable presentation: *
* CASE inhibit presentation: *
* CASE word underscore: *
* CASE vertical tab: *
* CASE switch: *
* Move the SCSDatapointer 1 byte ahead *
* subtract 1 from the length remaining *
* BREAK *
**********************************************************/
case BACKSPACE_CC:
case EXPANDED_BACKSPACE_CC:
case UNITBACKSPACE_CC:
case BEL_CC:
case CARRIAGE_RETURN_CC:
case SUBSCRIPT_CC:
case SUPERSCRIPT_CC:
case FORM_FEED_CC:
case REQUIRED_FORM_FEED_CC:
case HORIZONTAL_TAB_CC:
case INDENT_TAB_CC:
case LINE_FEED_CC:
case INDEX_RETURN_CC:
case REQUIRED_NEW_LINE_CC:
case NEW_LINE_CC:
case INTERCHANGE_RECORD_SEPARATOR_CC:
case ENABLE_PRESENTATION_CC:
case INHIBIT_PRESENTATION_CC:
case WORD_UNDERSCORE_CC:
case VERTICAL_TAB_CC:
case SHIFT_OUT_CC:
case SHIFT_IN_CC:
case SUBSTITUTE_CC:
case SWITCH_CC:
case NULL_CC:
offset++;
len--;
break;
/**********************************************************
* CASE presentation position: *
* IF we have all the data for the command *
* THEN *
* CALL PRESENTATIONPOSITION(function code from *
* command, value from command) to move to the *
* presentations position specified *
* Subtract the size of the PP command from the *
* length field in the print message *
* Add the size of the PP command to the work *
* pointer so that it points to the next *
* command *
* ELSE *
* Flag that there is no more stuff to process *
* BREAK *
**********************************************************/
case PRESENTATION_POSITION_CC:
if(len >= PP_STRUCT_LEN)
{
switch(buf[offset+1])
{
/*************************************************
* CASE Absolute Horizontal Presentation Position *
* CASE Absolute Verital Presentation Position *
* CASE Relative Horizontal Presentation Position *
* CASE Relative Verital Presentation Position *
* BREAK *
*************************************************/
case PPCODE_AHPP:
case PPCODE_AVPP:
case PPCODE_RHPP:
case PPCODE_RVPP:
offset += PP_STRUCT_LEN;
len -= PP_STRUCT_LEN;
fRC = true;
break;
default:
fRC = false;
fDone = true; // we are done here
} /* end switch */
} else {
fDone = true; // not enough left to process
}
break;
/**********************************************************
* CASE set attribute: *
* IF we have all the data for the command *
* THEN *
* CALL SETATTRIBUTE(type from command, value from *
* command to set the attribute *
* Subtract the size of the SA command from the *
* length field in the print message *
* Add the size of the SA command to the work *
* pointer so that it points to the next *
* command *
* ELSE *
* Flag that there is no more stuff to process *
* BREAK *
**********************************************************/
case SET_ATTRIBUTE_CC:
if(len >= SA_STRUCT_LEN)
{
switch(buf[offset+1])
{
/*************************************************
* CASE ATTR_CHAR_SET *
* we don't support the other attributes on the *
* the server. *
* BREAK *
*************************************************/
case ATTR_CHAR_SET:
offset += SA_STRUCT_LEN;
len -= SA_STRUCT_LEN;
fRC = true;
break;
default:
fRC = false;
fDone = true;
} /* end switch */
} else {
fDone = true;
}
break;
/**********************************************
* case 2B is a multibyte command *
* 2BCCnntt.... *
* CC is the command class (D1, D2, etc) *
* nn is the number of bytes left in the *
* command including this nn byte. *
* tt is the type *
**********************************************/
case CSP_CC:
if ( (len >= 3) &&
(len >= (buf[offset + 2] + 2) ) )
{
int count = buf[offset+2];
switch(buf[offset+1])
{
/*************************************************
* CASE set graphic error action: *
* CASE set horizontal format: *
* CASE set line density: *
* CASE set vertical format: *
* BREAK *
*************************************************/
case GRAPHIC_ERROR_ACTION_CC:
case HORIZONTAL_FORMAT_CC:
case LINE_DENSITY_CC:
case VERTICAL_FORMAT_CC:
len -= (count + 2);
offset += (count + 2);
fRC = true;
break;
/*************************************************
* CASE FontClass *
* a FONTCLASS is class 'D1'X. The commands *
* are SFG, SCG and SCGL, BES, EES *
* casentry type *
* CASE SFG *
* CASE BES *
* CASE EES *
* CASE SCG *
* CASE SFG *
* Set as SCS data and advance past command *
* BREAK *
* DEFAULT *
* Not SCS and we are done. *
* BREAK *
* BREAK *
*************************************************/
case FONTCLASS:
{
switch (buf[offset+3]) // switch on the type
{
case SFG_CC:
case BES_CC:
case EES_CC:
case SCG_CC:
case SCGL_CC:
{
len -= (count + 2);
offset += (count + 2);
fRC = true;
break;
} /* endcase */
default:
{
fRC = false;
fDone = true;
break;
}
} /* endswitch */
break;
} /* end CASE D1 */
/*************************************************
* CASE D2: *
* casentry type *
* CASE SetHorzTabs (STAB) *
* CASE SetPrintDensity *
* CASE SetLineSpacing *
* CASE SetSingleLineDistance *
* CASE SetHorizontalMargins *
* CASE SetVerticalMargins *
* CASE SJM command *
* CASE JTF command *
* CASE SetErrorAction *
* CASE SetInitialConditions *
* CASE SetIndentLevel *
* CASE SetPresentationColor *
* CASE SetPresentationPageMedia *
* CASE SetPrinterSetup *
* Set as SCS data *
* Advance past this command *
* BREAK *
* DEFAULT *
* Not SCS and we are done. *
* BREAK *
* ENDCASE *
* BREAK *
*************************************************/
case DOGTWO:
{
switch (buf[offset+3]) // switch on the type
{
case STAB_CC:
case PRINT_DENSITY_CC:
case SET_LINESPACE_CC:
case SET_LINEDISTANCE_CC:
case SET_HORZMARGINS_CC:
case SET_VERTMARGINS_CC:
case SET_ERROR_ACTION_CC:
case SET_INITCOND_CC:
case SET_INDENTLV_CC:
case SET_JUSTIFYMODE_CC:
case JUSTIFY_TEXTFIELD_CC:
case SET_PRESCOLOR_CC:
case SET_PRESPAGESIZE_CC:
case SET_PPAGEMEDIA_CC:
case SET_PRINTERSETUP_CC:
case RELEASE_LEFT_MARGIN_CC:
len -= (count+ 2);
offset += (count+ 2);
fRC = true;
break;
default:
fRC = false;
fDone = true;
break;
} /* endswitch */
break;
} /* end CASE D2 */
/*************************************************
* CASE D3: *
* casentry type *
* CASE SetTextOrientataion *
* Set as SCS data *
* Advance past this command *
* DEFAULT *
* Not SCS data and we are done *
* BREAK *
* ENDCASE *
* BREAK *
*************************************************/
case DOGTHREE:
{
switch (buf[offset+3]) // switch on the type
{
case STO_CC:
{
len -= (count+ 2);
offset += (count+ 2);
fRC = true;
break;
}
default:
{
fRC = false;
fDone = true;
}
} /* endswitch */
break;
} /* end CASE D3 */
/*************************************************
* CASE D4: *
* casentry type *
* CASE Begin Under Score *
* CASE End Under Score *
* CASE Begin Over Strike *
* CASE End Over Strike *
* Set as SCS data. *
* advance past this command *
* DEFAULT *
* NOT SCS and we are done *
* BREAK *
* ENDCASE *
* BREAK *
*************************************************/
case DOGFOUR:
{
switch (buf[offset+3]) // switch on the type
{
case BUS_CC:
case EUS_CC:
case BOS_CC:
case EOS_CC:
{
len -= (count+ 2);
offset += (count+ 2);
fRC = true;
break;
}
default:
{
fRC = false;
fDone = true;
break;
}
} /* endswitch */
break;
} /* end CASE D4 */
/*************************************************
* CASE FD: *
* casentry type *
* CASE Define Grid Lines *
* CASE Set IGC Type *
* CASE Set Font Size Scaling *
* CASE Set Presentation of Control Char *
* Set as SCS data. *
* advance past this command *
* DEFAULT *
* NOT SCS and we are done *
* BREAK *
* ENDCASE *
* BREAK *
*************************************************/
case FOXDOG:
{
switch (buf[offset+3]) // switch on the type
{
case DGL_CC:
case SIT_CC:
case SFSS_CC:
case SPCC_CC:
{
len -= (count+ 2);
offset += (count+ 2);
fRC = true;
break;
}
default:
{
fRC = false;
fDone = true;
break;
}
} /* endswitch */
break;
} /* end CASE FD */
/*************************************************
* DEFAULT: *
* NOT SCS and we are done *
* BREAK *
*************************************************/
default:
fRC = false;
fDone = true;
break;
} /* end of switch */
} else {
fDone = true;
}
break;
/**********************************************************
* CASE ASCII Transparency *
* CASE SCS transparent: *
**********************************************************/
case ASCII_TRNSPRNT_CC:
case TRANSPARENT_CC:
if ((len >= 2) &&
(len >= (buf[offset + 1] + 2) ) )
{
len -= buf[offset + 1] + 2;
offset += buf[offset + 1] + 2;
fRC = true;
} else {
fDone = true;
} /* endif */
break;
/**********************************************************
* Any other control codes are unsupported. *
**********************************************************/
/**********************************************************
* DEFAULT: *
* Not SCS data, we are done. *
* BREAK *
**********************************************************/
default:
fRC = false;
fDone = true;
break;
}
} else {
/*************************************************************/
/* byte is >= 0x40 and is just a regular character, so */
/* goto next byte - we can't say it is SCS data unless we */
/* have some SCS commands - EBCDIC text only will not show up*/
/* as SCS data. */
/*************************************************************/
len--;
offset++;
}
}
return fRC;
} // dataIsSCS()
/** sniffs the data and tells you what it appears to be.
* @param buf The data buffer.
* @param offset Offset into the data buffer to start at.
* @param len The number of bytes to analyze.
* @return A string with the server Printer Device Type
* value of what this data is most likely (*SCS,
* *AFPDS or *USERASCII).
**/
public static String sniff(byte[] buf, int offset, int len)
{
String str = DT_USERASCII;
if (dataIsAFP(buf, offset, len))
{
str = DT_AFPDS;
} else {
if (dataIsSCS(buf, offset, len))
{
str = DT_SCS;
}
}
return str;
}
// bunch of constants used for breaking SCS data stream
static final byte ASCII_TRNSPRNT_CC = (byte)0x03;
static final byte BACKSPACE_CC = (byte)0x16;
static final byte UNITBACKSPACE_CC = (byte)0x1A;
static final byte BEL_CC = (byte)0x2F;
static final byte CARRIAGE_RETURN_CC = (byte)0x0D;
static final byte ENABLE_PRESENTATION_CC = (byte)0x14;
static final byte EXPANDED_BACKSPACE_CC = (byte)0x36;
static final byte FORM_FEED_CC = (byte)0x0C;
static final byte GRAPHIC_ESCAPE_CC = (byte)0x08;
static final byte HORIZONTAL_TAB_CC = (byte)0x05;
static final byte INDENT_TAB_CC = (byte)0x39;
static final byte INDEX_RETURN_CC = (byte)0x33;
static final byte INHIBIT_PRESENTATION_CC = (byte)0x24;
static final byte INTERCHANGE_RECORD_SEPARATOR_CC = (byte)0x1E;
static final byte LINE_FEED_CC = (byte)0x25;
static final byte NEW_LINE_CC = (byte)0x15;
static final byte NULL_CC = (byte)0x00;
static final byte PRESENTATION_POSITION_CC = (byte)0x34;
static final byte REQUIRED_FORM_FEED_CC = (byte)0x3A;
static final byte REQUIRED_NEW_LINE_CC = (byte)0x06;
static final byte SPACE_CC = (byte)0x40;
static final byte REQUIRED_SPACE_CC = (byte)0x41;
static final byte SET_ATTRIBUTE_CC = (byte)0x28;
static final byte SHIFT_OUT_CC = (byte)0x0E;
static final byte SHIFT_IN_CC = (byte)0x0F;
static final byte SWITCH_CC = (byte)0x2A;
static final byte CSP_CC = (byte)0x2B;
static final byte SUBSTITUTE_CC = (byte)0x3F;
static final byte GRAPHIC_ERROR_ACTION_CC = (byte)0xC8;
static final byte HORIZONTAL_FORMAT_CC = (byte)0xC1;
static final byte LINE_DENSITY_CC = (byte)0xC6;
static final byte NUMERIC_SPACE_CC = (byte)0xE1;
static final byte SUBSCRIPT_CC = (byte)0x38;
static final byte SUPERSCRIPT_CC = (byte)0x09;
static final byte SYLLABLE_HYPHEN_CC = (byte)0xCA;
static final byte TRANSPARENT_CC = (byte)0x35;
static final byte VERTICAL_CHANNEL_SELECT_CC = (byte)0x04;
static final byte VERTICAL_TAB_CC = (byte)0x0B;
static final byte WORD_UNDERSCORE_CC = (byte)0x23;
/******************************************************************************/
/* the following commands all begin with 2BD1 */
/******************************************************************************/
static final byte FONTCLASS = (byte)0xD1;
static final byte SCG_CC = (byte)0x01;
static final byte SCGL_CC = (byte)0x81;
static final byte SFG_CC = (byte)0x05;
static final byte BES_CC = (byte)0x8A;
static final byte EES_CC = (byte)0x8E;
/******************************************************************************/
/* the following set all begin with = (byte)0x2BD2 and here we define the type byte */
/******************************************************************************/
static final byte DOGTWO = (byte)0xD2;
static final byte STAB_CC = (byte)0x01;
static final byte JUSTIFY_TEXTFIELD_CC = (byte)0x03;
static final byte SET_INDENTLV_CC = (byte)0x07;
static final byte SET_LINESPACE_CC = (byte)0x09;
static final byte RELEASE_LEFT_MARGIN_CC = (byte)0x0B;
static final byte SET_JUSTIFYMODE_CC = (byte)0x0D;
static final byte SET_HORZMARGINS_CC = (byte)0x11;
static final byte SET_LINEDISTANCE_CC = (byte)0x15;
static final byte PRINT_DENSITY_CC = (byte)0x29;
static final byte SET_PRESCOLOR_CC = (byte)0x2D;
static final byte SET_PRESPAGESIZE_CC = (byte)0x40;
static final byte SET_INITCOND_CC = (byte)0x45;
static final byte SET_PPAGEMEDIA_CC = (byte)0x48;
static final byte SET_VERTMARGINS_CC = (byte)0x49;
static final byte SET_PRINTERSETUP_CC = (byte)0x4C;
static final byte SET_ERROR_ACTION_CC = (byte)0x85;
static final byte VERTICAL_FORMAT_CC = (byte)0xC2;
/******************************************************************************/
/* the following set all begin with = (byte)0x2BD3 and here we define the type byte */
/******************************************************************************/
static final byte DOGTHREE = (byte)0xD3;
static final byte STO_CC = (byte)0xF6;
/******************************************************************************/
/* the following set all begin with 0x2BD4 and here we define the type byte */
/******************************************************************************/
static final byte DOGFOUR = (byte)0xD4;
static final byte BUS_CC = (byte)0x0A;
static final byte EUS_CC = (byte)0x0E;
static final byte BOS_CC = (byte)0x72;
static final byte EOS_CC = (byte)0x76;
/******************************************************************************/
/* the following set all begin with 0x2BFD and here we define the type byte */
/******************************************************************************/
static final byte FOXDOG = (byte)0xFD;
static final byte DGL_CC = (byte)0x00;
static final byte SIT_CC = (byte)0x01;
static final byte SFSS_CC = (byte)0x02;
static final byte SPCC_CC = (byte)0x03;
/**********************************************************************
* Structure for Presentation Position *
* 0x34ccvv - cc = code; vv = value; *
***********************************************************************/
static final byte PP_STRUCT_LEN = 0x03; // length of PP structure
/* defines for PPcode field */
static final byte PPCODE_AHPP = (byte)0xC0; /* Absolute Horizontal */
static final byte PPCODE_AVPP = (byte)0xC4; /* Absolute Veritcal */
static final byte PPCODE_RHPP = (byte)0xC8; /* Relative Horizontal */
static final byte PPCODE_RVPP = (byte)0x4C; /* Relative Veritcal */
/**********************************************************************
* Structure for Set Attribute *
* 0x28ttvv tt=type; vv = value *
**********************************************************************/
static final byte SA_STRUCT_LEN = 0x03; // length of SA structure
/* Defines for the type field */
static final byte ATTR_RESET = (byte)0x00; /* Reset */
static final byte ATTR_COLOR = (byte)0x42; /* Set color */
static final byte ATTR_HILITE = (byte)0x41; /* Set highlight */
static final byte ATTR_CHAR_SET = (byte)0x43; /* Set character set */
}