001    /*
002     *  Licensed to the Apache Software Foundation (ASF) under one
003     *  or more contributor license agreements.  See the NOTICE file
004     *  distributed with this work for additional information
005     *  regarding copyright ownership.  The ASF licenses this file
006     *  to you under the Apache License, Version 2.0 (the
007     *  "License"); you may not use this file except in compliance
008     *  with the License.  You may obtain a copy of the License at
009     *  
010     *    http://www.apache.org/licenses/LICENSE-2.0
011     *  
012     *  Unless required by applicable law or agreed to in writing,
013     *  software distributed under the License is distributed on an
014     *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     *  KIND, either express or implied.  See the License for the
016     *  specific language governing permissions and limitations
017     *  under the License. 
018     *  
019     */
020    
021    package org.apache.directory.server.dns.io.encoder;
022    
023    
024    import java.io.IOException;
025    
026    import org.apache.directory.server.dns.messages.RecordClass;
027    import org.apache.directory.server.dns.messages.RecordType;
028    import org.apache.directory.server.dns.messages.ResourceRecord;
029    import org.apache.mina.core.buffer.IoBuffer;
030    
031    
032    /**
033     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
034     * @version $Rev: 725712 $, $Date: 2008-12-11 16:32:04 +0100 (Thu, 11 Dec 2008) $
035     */
036    public abstract class ResourceRecordEncoder implements RecordEncoder
037    {
038        public void put( IoBuffer byteBuffer, ResourceRecord record ) throws IOException
039        {
040            putDomainName( byteBuffer, record.getDomainName() );
041            putRecordType( byteBuffer, record.getRecordType() );
042            putRecordClass( byteBuffer, record.getRecordClass() );
043    
044            byteBuffer.putInt( record.getTimeToLive() );
045    
046            putResourceRecord( byteBuffer, record );
047        }
048    
049    
050        protected abstract void putResourceRecordData( IoBuffer byteBuffer, ResourceRecord record );
051    
052    
053        protected void putResourceRecord( IoBuffer byteBuffer, ResourceRecord record )
054        {
055            int startPosition = byteBuffer.position();
056            byteBuffer.position( startPosition + 2 );
057    
058            putResourceRecordData( byteBuffer, record );
059    
060            putDataSize( byteBuffer, startPosition );
061        }
062    
063    
064        protected void putDataSize( IoBuffer byteBuffer, int startPosition )
065        {
066            int endPosition = byteBuffer.position();
067            short length = ( short ) ( endPosition - startPosition - 2 );
068    
069            byteBuffer.position( startPosition );
070            byteBuffer.putShort( length );
071            byteBuffer.position( endPosition );
072        }
073    
074    
075        /**
076         * <domain-name> is a domain name represented as a series of labels, and
077         * terminated by a label with zero length.
078         * 
079         * @param byteBuffer the ByteBuffer to encode the domain name into
080         * @param domainName the domain name to encode
081         */
082        protected void putDomainName( IoBuffer byteBuffer, String domainName )
083        {
084            String[] labels = domainName.split( "\\." );
085    
086            for ( int ii = 0; ii < labels.length; ii++ )
087            {
088                byteBuffer.put( ( byte ) labels[ii].length() );
089    
090                char[] characters = labels[ii].toCharArray();
091                for ( int jj = 0; jj < characters.length; jj++ )
092                {
093                    byteBuffer.put( ( byte ) characters[jj] );
094                }
095            }
096    
097            byteBuffer.put( ( byte ) 0x00 );
098        }
099    
100    
101        protected void putRecordType( IoBuffer byteBuffer, RecordType recordType )
102        {
103            byteBuffer.putShort( recordType.convert() );
104        }
105    
106    
107        protected void putRecordClass( IoBuffer byteBuffer, RecordClass recordClass )
108        {
109            byteBuffer.putShort( recordClass.convert() );
110        }
111    
112    
113        /**
114         * <character-string> is a single length octet followed by that number
115         * of characters.  <character-string> is treated as binary information,
116         * and can be up to 256 characters in length (including the length octet).
117         * 
118         * @param byteBuffer The byte buffer to encode the character string into.
119         * @param characterString the character string to encode
120         */
121        protected void putCharacterString( IoBuffer byteBuffer, String characterString )
122        {
123            byteBuffer.put( ( byte ) characterString.length() );
124    
125            char[] characters = characterString.toCharArray();
126    
127            for ( int ii = 0; ii < characters.length; ii++ )
128            {
129                byteBuffer.put( ( byte ) characters[ii] );
130            }
131        }
132    }