/* * [EncodingHead.java] * * Summary: Generate a page to describe an encoding. * * Copyright: (c) 2013-2017 Roedy Green, Canadian Mind Products, http://mindprod.com * * Licence: This software may be copied and used freely for any purpose but military. * http://mindprod.com/contact/nonmil.html * * Requires: JDK 1.8+ * * Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/ * * Version History: * 1.8 2009-02-06 include go package in ZIP bundle. */ package com.mindprod.htmlmacros.macro; import com.mindprod.common18.ST; import com.mindprod.entities.EntifyStrings; import com.mindprod.fastcat.FastCat; import com.mindprod.htmlmacros.support.GoogleAdSense; import com.mindprod.htmlmacros.support.Indexing; import java.io.UnsupportedEncodingException; import static java.lang.System.*; /** * Generate a page to describe an encoding. * * @author Roedy Green, Canadian Mind Products * @version 1.0 2013-01-31 initial version * @since 2013-01-31 */ public final class EncodingHead extends Head { /** * how to use the macro */ private static final String USAGE = "\nmacro EncodingHead UNICODE-LE 16 little (encoding, bits, big/little endian)"; /** * Generate a 16 x 16 encoding chart * * @param title title for the chart * @param encoding name of the encoding * @param bits 8 or 16 bit * @param bigEndian true for big endian. use true for 8 bit. */ private static String generateEncodingChart( final String title, final String encoding, final int bits, boolean bigEndian ) throws UnsupportedEncodingException { assert bits == 8 || bits == 16 : "only handle 8 or 16 bit encodings"; // how many samples to generate int samples = bits == 16 ? 512 : 256; // build a sample set of bytes to interpret in that coding byte[] sampleBytes = new byte[ bits == 16 ? samples * 2 : samples ]; for ( int i = 0; i < samples; i++ ) { final int j; if ( bits == 16 ) { if ( bigEndian ) { j = i * 2 + 1; } else { j = i * 2; } } else { j = i; } sampleBytes[ j ] = ( byte ) i; } // convert bute to unicode chars final String sampleChars = new String( sampleBytes, encoding ); assert sampleChars.length() == samples : "Cannot handle variable length encodings " + sampleChars.length(); // build n x 16 table final int rows = samples / 16; final FastCat sb = new FastCat( rows * 16 * 6 + rows * 2 + 10 ); int i = 0; sb.append( "\n" ); sb.append( "\n" ); sb.append( "\n" ); sb.append( "\n" ); for ( int row = 0; row < rows; row++ ) { sb.append( "\n" ); for ( int col = 0; col < 16; col++ ) { sb.append( "\n" ); i++; } sb.append( "" ); } sb.append( "
" ); sb.append( title ); sb.append( "
" ); sb.append( title ); sb.append( "
" ); char c = sampleChars.charAt( i ); // make control chars visible c = makeVisible( c ); sb.append( "" ); sb.append( EntifyStrings.toHTMLEntity( c ) ); sb.append( "
" ); sb.append( ST.toLZHexString( i, bits == 16 ? 4 : 2 ) ); sb.append( "
\n" ); if ( bits == 16 ) { sb.append( "

Only the first " + samples + " characters of 65536 are shown.

\n" ); } return sb.toString(); } /** * make this character into a visible char * * @param c the char in Unicode, what we want to display as glyph for given slot. * * @return the char transformed if necessary to make is visible */ private static char makeVisible( char c ) { if ( 0 <= c && c <= 0x20 ) { c += 0x2400; } else if ( c == 0xad ) { c = 0x96; } else if ( c == 0x7f ) { c = 0x2421; /* letters DEL */ } else if ( c == 0xfffd ) /* unassigned */ { c = 0x25a2; /* white square with rounded corners */ } else if ( 0x80 <= c && c <= 0xa0 ) { // no glyphs, so use bullet; c = 0x2022; } return c; } /** * Generate the header for a Encoding chart * * @param parms parameters from macro command line. * parms[0] = encoding * parm[1] = bits * parm[2] = big/little endian * @param quiet true if want output suppressed. * @param verbose @return expanded macro HTML */ public String expandMacro( String[] parms, final boolean quiet, final boolean verbose ) { if ( !quiet ) { out.print( "E" ); } if ( parms.length != 3 ) { throw new IllegalArgumentException( USAGE ); } String encoding = parms[ 0 ]; final int bits = Integer.parseInt( parms[ 1 ] ); final boolean bigEndian; if ( parms[ 2 ].equals( "big" ) ) { bigEndian = true; } else if ( parms[ 2 ].equals( "little" ) ) { bigEndian = false; } else if ( parms[ 2 ].equals( "-" ) ) { bigEndian = true; } else { throw new IllegalArgumentException( USAGE ); } String title = encoding + " " + bits + "-bit"; if ( bits == 16 ) { title += bigEndian ? " Big Endian" : " Little Endian"; } title += " Encoding"; String icon = "icon16/encodingchart.png"; String sectionFile = "jgloss/jgloss.html"; String sectionTitle = "Java Glossary"; String subSectionFile = "jgloss/encoding.html"; String subSectionTitle = "Encodings"; String keywords = encoding + ",encoding,encoding chart,charset,charset chart,character set," + "" + "character set chart,translation,cast of characters,glyphs"; String image = "icon64/encodingchart.png"; final FastCat sb = new FastCat( 2 ); sb.append( generalHead( title, encoding, title, title, "titlesubsubsection", keywords, icon, null, image, null, null, sectionFile, sectionTitle, subSectionFile, subSectionTitle, null, null, null, null, Indexing.NONE, GoogleAdSense.MEDIUM_RECTANGLE, null, null ) ); try { sb.append( generateEncodingChart( title, encoding, bits, bigEndian ) ); } catch ( UnsupportedEncodingException e ) { throw new IllegalArgumentException( "no such encoding " + encoding ); } // we do not generate the foot return sb.toString(); } }