001: /*
002:
003: Derby - Class org.apache.derby.iapi.services.classfile.ClassFormatOutput
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.iapi.services.classfile;
023:
024: import org.apache.derby.iapi.services.io.AccessibleByteArrayOutputStream;
025: import java.io.DataOutputStream;
026: import java.io.IOException;
027: import java.io.OutputStream;
028:
029: /** A wrapper around DataOutputStream to provide input functions in terms
030: of the types defined on pages 83 of the Java Virtual Machine spec.
031:
032: For this types use these methods of DataOutputStream
033: <UL>
034: <LI>float - writeFloat
035: <LI>long - writeLong
036: <LI>double - writeDouble
037: <LI>UTF/String - writeUTF
038: <LI>U1Array - write(byte[])
039: </UL>
040: */
041:
042: public final class ClassFormatOutput extends DataOutputStream {
043:
044: public ClassFormatOutput() {
045: this (512);
046: }
047:
048: public ClassFormatOutput(int size) {
049: this (new AccessibleByteArrayOutputStream(size));
050: }
051:
052: public ClassFormatOutput(java.io.OutputStream stream) {
053: super (stream);
054: }
055:
056: public void putU1(int i) throws IOException {
057: // ensure the format of the class file is not
058: // corrupted by writing an incorrect, truncated value.
059: if (i > 255)
060: ClassFormatOutput.limit("U1", 255, i);
061: write(i);
062: }
063:
064: public void putU2(int i) throws IOException {
065: putU2("U2", i);
066:
067: }
068:
069: public void putU2(String limit, int i) throws IOException {
070:
071: // ensure the format of the class file is not
072: // corrupted by writing an incorrect, truncated value.
073: if (i > 65535)
074: ClassFormatOutput.limit(limit, 65535, i);
075: write(i >> 8);
076: write(i);
077: }
078:
079: public void putU4(int i) throws IOException {
080: writeInt(i);
081: }
082:
083: public void writeTo(OutputStream outTo) throws IOException {
084: ((AccessibleByteArrayOutputStream) out).writeTo(outTo);
085: }
086:
087: /**
088: Get a reference to the data array the class data is being built
089: in. No copy is made.
090: */
091: public byte[] getData() {
092: return ((AccessibleByteArrayOutputStream) out)
093: .getInternalByteArray();
094: }
095:
096: /**
097: * Throw an ClassFormatError if a limit of the Java class file format is reached.
098: * @param name Terse limit description from JVM spec.
099: * @param limit What the limit is.
100: * @param value What the value for the current class is
101: * @throws IOException Thrown when limit is exceeded.
102: */
103: static void limit(String name, int limit, int value)
104: throws IOException {
105: throw new IOException(name + "(" + value + " > " + limit + ")");
106: }
107: }
|