## An encoder for ASCII7#implement Converter;include "sys.m";include "converter.m";# module private constantsNAME : con "8859_1";BPC : con 1;SUBCHARS := array[] of {'\uFFFD'};SUBBYTES := array[] of {byte '?'};# module private dataisInitialized : int;highHalfZoneCode := 0;# Peform initialization. This should only# be called once after loading and before# its first use. If called a second time# an error will result. If it is not called# before being used, then the module behavior# is undefined.# return nil==no err else err message.init() : string{ # set module instance data name = NAME; reset(); return( nil );}toBytes( input : array of int, #chars to convert output : array of byte #store bytes here ) : (int,int) #RC, bytes written{ inEnd := len input; outEnd := len output; outOff := char_off; inputChar : int; # Input character to be converted outputByte : array of byte ; # Output byte written to output tmpArray := array[1] of byte; inputSize := 0; # Size of input outputSize := 0; # Size of output if (highHalfZoneCode != 0) { inputChar = highHalfZoneCode; highHalfZoneCode = 0; if (input[char_off] >= 16rdc00 && input[char_off] <= 16rdfff) { # This is legal UTF16 sequence. bad_len = 1; return( RC_UNKNOWN, 0 ); } else { # This is illegal UTF16 sequence. bad_len = 0; return( RC_MALFORMED, 0 ); } } # Loop until we hit the end of the input while(char_off < inEnd) { outputByte = tmpArray; # Get the input character inputChar = input[char_off]; # default outputSize outputSize = 1; # Assume this is a simple character inputSize = 1; # Is this a high surrogate? if(inputChar >= '\uD800' && inputChar <= '\uDBFF') { # Is this the last character in the input? if (char_off + 1 == inEnd) { highHalfZoneCode = inputChar; break; } # Is there a low surrogate following? inputChar = input[char_off + 1]; if (inputChar >= '\uDC00' && inputChar <= '\uDFFF') { # We have a valid surrogate pair. Too bad we don't map # surrogates. Is substitution enabled? if (submode) { outputByte = subbytes; outputSize = len subbytes; inputSize = 2; } else { bad_len = 2; return( RC_UNKNOWN, 0 ); } } else { # We have a malformed surrogate pair bad_len = 1; return( RC_MALFORMED, 0 ); } } # Is this an unaccompanied low surrogate? else if (inputChar >= '\uDC00' && inputChar <= '\uDFFF') { bad_len = 1; return( RC_MALFORMED, 0 ); } # Not part of a surrogate, so try to convert else { # Is this character mappable? if (inputChar <= '\u00FF') { outputByte[0] = byte inputChar; } else { # Is substitution enabled? if (submode) { outputByte = subbytes; outputSize = len subbytes; } else { bad_len = 1; return( RC_UNKNOWN, 0 ); } } } # If we don't have room for the output, throw an exception if ( (byte_off + outputSize) > outEnd) return( RC_BUFFULL, 0 ); # Put the byte in the output buffer for (i := 0; i < outputSize; i++) { output[byte_off++] = outputByte[i]; } char_off += inputSize; } # Return the length written to the output buffer return( RC_OK, byte_off-outOff );}toChars( input : array of byte, #bytes to convert output : array of int #store chars here ) : (int,int) #RC, bytes written{ # Loop until we hit the end of the input for( (i,j):=(0,0); i < len input; i++ ) { byte_off++; #increment buffer index # If we don't have room for the output, throw an exception if ( j >= len output ) return( RC_BUFFULL, 0 ); # Convert the input byte input_val := int input[i]; if ( input_val < 0 ) { input_val += 256; } output[j] = input_val; j++; char_off++; } # Return the length written to the output buffer return( RC_OK, j );}## return the maximum bytes per char (BPC) for the encoding#maxBPC() : int{ return( BPC );}## can a character be mapped?#isMapped( ch : int ) : int{ junk := ch; return( 1 );}## reinitialize module instance data. If this is called# prior to init() then it is equivalent to calling init().#reset(){ submode = 1; subbytes = array[] of {byte '0'}; subchars = array[] of {'?'}; char_off = byte_off = bad_len = 0; isInitialized = 1;}
#
# An encoder for ASCII7
#
implement Converter;
include "sys.m";
include "converter.m";
# module private constants
NAME : con "8859_1";
BPC : con 1;
SUBCHARS := array[] of {'\uFFFD'};
SUBBYTES := array[] of {byte '?'};
# module private data
isInitialized : int;
highHalfZoneCode := 0;
# Peform initialization. This should only
# be called once after loading and before
# its first use. If called a second time
# an error will result. If it is not called
# before being used, then the module behavior
# is undefined.
# return nil==no err else err message.
init() : string
{
# set module instance data
name = NAME;
reset();
return( nil );
}
toBytes( input : array of int, #chars to convert
output : array of byte #store bytes here
) : (int,int) #RC, bytes written
{
inEnd := len input;
outEnd := len output;
outOff := char_off;
inputChar : int; # Input character to be converted
outputByte : array of byte ; # Output byte written to output
tmpArray := array[1] of byte;
inputSize := 0; # Size of input
outputSize := 0; # Size of output
if (highHalfZoneCode != 0)
{
inputChar = highHalfZoneCode;
highHalfZoneCode = 0;
if (input[char_off] >= 16rdc00 && input[char_off] <= 16rdfff)
{
# This is legal UTF16 sequence.
bad_len = 1;
return( RC_UNKNOWN, 0 );
}
else
{
# This is illegal UTF16 sequence.
bad_len = 0;
return( RC_MALFORMED, 0 );
}
}
# Loop until we hit the end of the input
while(char_off < inEnd)
{
outputByte = tmpArray;
# Get the input character
inputChar = input[char_off];
# default outputSize
outputSize = 1;
# Assume this is a simple character
inputSize = 1;
# Is this a high surrogate?
if(inputChar >= '\uD800' && inputChar <= '\uDBFF')
{
# Is this the last character in the input?
if (char_off + 1 == inEnd)
{
highHalfZoneCode = inputChar;
break;
}
# Is there a low surrogate following?
inputChar = input[char_off + 1];
if (inputChar >= '\uDC00' && inputChar <= '\uDFFF')
{
# We have a valid surrogate pair. Too bad we don't map
# surrogates. Is substitution enabled?
if (submode)
{
outputByte = subbytes;
outputSize = len subbytes;
inputSize = 2;
}
else
{
bad_len = 2;
return( RC_UNKNOWN, 0 );
}
}
else
{
# We have a malformed surrogate pair
bad_len = 1;
return( RC_MALFORMED, 0 );
}
}
# Is this an unaccompanied low surrogate?
else if (inputChar >= '\uDC00' && inputChar <= '\uDFFF')
{
bad_len = 1;
return( RC_MALFORMED, 0 );
}
# Not part of a surrogate, so try to convert
else
{
# Is this character mappable?
if (inputChar <= '\u00FF')
{
outputByte[0] = byte inputChar;
}
else
{
# Is substitution enabled?
if (submode)
{
outputByte = subbytes;
outputSize = len subbytes;
}
else
{
bad_len = 1;
return( RC_UNKNOWN, 0 );
}
}
}
# If we don't have room for the output, throw an exception
if ( (byte_off + outputSize) > outEnd)
return( RC_BUFFULL, 0 );
# Put the byte in the output buffer
for (i := 0; i < outputSize; i++)
{
output[byte_off++] = outputByte[i];
}
char_off += inputSize;
}
# Return the length written to the output buffer
return( RC_OK, byte_off-outOff );
}
toChars( input : array of byte, #bytes to convert
output : array of int #store chars here
) : (int,int) #RC, bytes written
{
# Loop until we hit the end of the input
for( (i,j):=(0,0); i < len input; i++ )
{
byte_off++; #increment buffer index
# If we don't have room for the output, throw an exception
if ( j >= len output )
return( RC_BUFFULL, 0 );
# Convert the input byte
input_val := int input[i];
if ( input_val < 0 )
{
input_val += 256;
}
output[j] = input_val;
j++;
char_off++;
}
# Return the length written to the output buffer
return( RC_OK, j );
}
#
# return the maximum bytes per char (BPC) for the encoding
#
maxBPC() : int
{
return( BPC );
}
#
# can a character be mapped?
#
isMapped( ch : int ) : int
{
junk := ch;
return( 1 );
}
#
# reinitialize module instance data. If this is called
# prior to init() then it is equivalent to calling init().
#
reset()
{
submode = 1;
subbytes = array[] of {byte '0'};
subchars = array[] of {'?'};
char_off = byte_off = bad_len = 0;
isInitialized = 1;
}