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
021package org.apache.directory.server.dns.io.encoder;
022
023
024import java.io.IOException;
025
026import org.apache.directory.api.util.Strings;
027import org.apache.directory.server.dns.messages.RecordClass;
028import org.apache.directory.server.dns.messages.RecordType;
029import org.apache.directory.server.dns.messages.ResourceRecord;
030import org.apache.mina.core.buffer.IoBuffer;
031
032
033/**
034 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
035 */
036public 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     * &lt;domain-name&gt; 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        if ( !Strings.isEmpty( domainName ) )
085        {
086            String[] labels = domainName.split( "\\." );
087        
088
089            for ( String label : labels )
090            {
091                byteBuffer.put( ( byte ) label.length() );
092    
093                char[] characters = label.toCharArray();
094                
095                for ( char c : characters )
096                {
097                    byteBuffer.put( ( byte ) c );
098                }
099            }
100        }
101
102        byteBuffer.put( ( byte ) 0x00 );
103    }
104
105
106    protected void putRecordType( IoBuffer byteBuffer, RecordType recordType )
107    {
108        byteBuffer.putShort( recordType.convert() );
109    }
110
111
112    protected void putRecordClass( IoBuffer byteBuffer, RecordClass recordClass )
113    {
114        byteBuffer.putShort( recordClass.convert() );
115    }
116
117
118    /**
119     * &lt;character-string&gt; is a single length octet followed by that number
120     * of characters.  &lt;character-string&gt; is treated as binary information,
121     * and can be up to 256 characters in length (including the length octet).
122     * 
123     * @param byteBuffer The byte buffer to encode the character string into.
124     * @param characterString the character string to encode
125     */
126    protected void putCharacterString( IoBuffer byteBuffer, String characterString )
127    {
128        byteBuffer.put( ( byte ) characterString.length() );
129
130        char[] characters = characterString.toCharArray();
131
132        for ( int ii = 0; ii < characters.length; ii++ )
133        {
134            byteBuffer.put( ( byte ) characters[ii] );
135        }
136    }
137}