+ DBFReader cannot write anythng to a DBF file. For creating DBF files
+ use DBFWriter.
+
+
+ Fetching rocord is possible only in the forward direction and
+ cannot re-wound. In such situation, a suggested approach is to reconstruct the object.
+
+
+ The nextRecord() method returns an array of Objects and the types of these
+ Object are as follows:
+
+
+
+ | xBase Type | Java Type |
+
+
+
+ | C | String |
+
+
+ | N | Integer |
+
+
+ | F | Double |
+
+
+ | L | Boolean |
+
+
+ | D | java.util.Date |
+
+
+
+*/
+public class DBFReader extends DBFBase {
+
+ DataInputStream dataInputStream;
+ DBFHeader header;
+
+ /* Class specific variables */
+ boolean isClosed = true;
+
+ /**
+ Initializes a DBFReader object.
+
+ When this constructor returns the object
+ will have completed reading the hader (meta date) and
+ header information can be quried there on. And it will
+ be ready to return the first row.
+
+ @param InputStream where the data is read from.
+ */
+ public DBFReader( InputStream in) throws DBFException {
+
+ try {
+
+ this.dataInputStream = new DataInputStream( in);
+ this.isClosed = false;
+ this.header = new DBFHeader();
+ this.header.read( this.dataInputStream);
+
+ /* it might be required to leap to the start of records at times */
+ int t_dataStartIndex = this.header.headerLength - ( 32 + (32*this.header.fieldArray.length)) - 1;
+ if( t_dataStartIndex > 0) {
+
+ dataInputStream.skip( t_dataStartIndex);
+ }
+ }
+ catch( IOException e) {
+
+ throw new DBFException( e.getMessage());
+ }
+ }
+
+
+ public String toString() {
+
+ StringBuffer sb = new StringBuffer( this.header.year + "/" + this.header.month + "/" + this.header.day + "\n"
+ + "Total records: " + this.header.numberOfRecords +
+ "\nHEader length: " + this.header.headerLength +
+ "");
+
+ for( int i=0; i 0 && !Utils.contains( t_float, (byte)'?')) {
+
+ recordObjects[i] = new Float( new String( t_float));
+ }
+ else {
+
+ recordObjects[i] = null;
+ }
+ }
+ catch( NumberFormatException e) {
+
+ throw new DBFException( "Failed to parse Float: " + e.getMessage());
+ }
+
+ break;
+
+ case 'N':
+
+ try {
+
+ byte t_numeric[] = new byte[ this.header.fieldArray[i].getFieldLength()];
+ dataInputStream.read( t_numeric);
+ t_numeric = Utils.trimLeftSpaces( t_numeric);
+
+ if( t_numeric.length > 0 && !Utils.contains( t_numeric, (byte)'?')) {
+
+ recordObjects[i] = new Double( new String( t_numeric));
+ }
+ else {
+
+ recordObjects[i] = null;
+ }
+ }
+ catch( NumberFormatException e) {
+
+ throw new DBFException( "Failed to parse Number: " + e.getMessage());
+ }
+
+ break;
+
+ case 'L':
+
+ byte t_logical = dataInputStream.readByte();
+ if( t_logical == 'Y' || t_logical == 't' || t_logical == 'T' || t_logical == 't') {
+
+ recordObjects[i] = Boolean.TRUE;
+ }
+ else {
+
+ recordObjects[i] = Boolean.FALSE;
+ }
+ break;
+
+ case 'M':
+ // TODO Later
+ recordObjects[i] = new String( "null");
+ break;
+
+ default:
+ recordObjects[i] = new String( "null");
+ }
+ }
+ }
+ catch( EOFException e) {
+
+ return null;
+ }
+ catch( IOException e) {
+
+ throw new DBFException( e.getMessage());
+ }
+
+ return recordObjects;
+ }
+}
diff --git a/dotnetdbf/original java src/DBFWriter.java b/dotnetdbf/original java src/DBFWriter.java
new file mode 100644
index 0000000..8d0e4f1
--- /dev/null
+++ b/dotnetdbf/original java src/DBFWriter.java
@@ -0,0 +1,350 @@
+/*
+ DBFWriter
+ Class for defining a DBF structure and addin data to that structure and
+ finally writing it to an OutputStream.
+
+ This file is part of JavaDBF packege.
+
+ author: anil@linuxense.com
+ license: LGPL (http://www.gnu.org/copyleft/lesser.html)
+
+ $Id: DBFWriter.java,v 1.9 2004/03/31 10:57:16 anil Exp $
+*/
+package com.linuxense.javadbf;
+import java.io.*;
+import java.util.*;
+
+/**
+ An object of this class can create a DBF file.
+
+ Create an object,
+ then define fields by creating DBFField objects and
+ add them to the DBFWriter object
+ add records using the addRecord() method and then
+ call write() method.
+*/
+public class DBFWriter extends DBFBase {
+
+ /* other class variables */
+ DBFHeader header;
+ Vector v_records = new Vector();
+ int recordCount = 0;
+ RandomAccessFile raf = null; /* Open and append records to an existing DBF */
+ boolean appendMode = false;
+
+ /**
+ Creates an empty Object.
+ */
+ public DBFWriter() {
+
+ this.header = new DBFHeader();
+ }
+
+ /**
+ Creates a DBFWriter which can append to records to an existing DBF file.
+ @param dbfFile. The file passed in shouls be a valid DBF file.
+ @exception Throws DBFException if the passed in file does exist but not a valid DBF file, or if an IO error occurs.
+ */
+ public DBFWriter( File dbfFile)
+ throws DBFException {
+
+ try {
+
+ this.raf = new RandomAccessFile( dbfFile, "rw");
+
+ /* before proceeding check whether the passed in File object
+ is an empty/non-existent file or not.
+ */
+ if( !dbfFile.exists() || dbfFile.length() == 0) {
+
+ this.header = new DBFHeader();
+ return;
+ }
+
+ header = new DBFHeader();
+ this.header.read( raf);
+
+ /* position file pointer at the end of the raf */
+ this.raf.seek( this.raf.length()-1 /* to ignore the END_OF_DATA byte at EoF */);
+ }
+ catch( FileNotFoundException e) {
+
+ throw new DBFException( "Specified file is not found. " + e.getMessage());
+ }
+ catch( IOException e) {
+
+ throw new DBFException( e.getMessage() + " while reading header");
+ }
+
+ this.recordCount = this.header.numberOfRecords;
+ }
+
+ /**
+ Sets fields.
+ */
+ public void setFields( DBFField[] fields)
+ throws DBFException {
+
+ if( this.header.fieldArray != null) {
+
+ throw new DBFException( "Fields has already been set");
+ }
+
+ if( fields == null || fields.length == 0) {
+
+ throw new DBFException( "Should have at least one field");
+ }
+
+ for( int i=0; i>8;
+
+ return num2;
+ }
+
+ public static int littleEndian(int value) {
+
+ int num1 = value;
+ int mask = 0xff;
+ int num2 = 0x00;
+
+ num2 |= num1 & mask;
+
+ for( int i=1; i<4; i++) {
+
+ num2<<=8;
+ mask <<= 8;
+ num2 |= (num1 & mask)>>(8*i);
+ }
+
+ return num2;
+ }
+
+ public static byte[] textPadding( String text, String characterSetName, int length) throws java.io.UnsupportedEncodingException {
+
+ return textPadding( text, characterSetName, length, Utils.ALIGN_LEFT);
+ }
+
+ public static byte[] textPadding( String text, String characterSetName, int length, int alignment) throws java.io.UnsupportedEncodingException {
+
+ return textPadding( text, characterSetName, length, alignment, (byte)' ');
+ }
+
+ public static byte[] textPadding( String text, String characterSetName, int length, int alignment,
+ byte paddingByte) throws java.io.UnsupportedEncodingException {
+
+ if( text.length() >= length) {
+
+ return text.substring( 0, length).getBytes( characterSetName);
+ }
+
+ byte byte_array[] = new byte[ length];
+ Arrays.fill( byte_array, paddingByte);
+
+ switch( alignment) {
+
+ case ALIGN_LEFT:
+ System.arraycopy( text.getBytes( characterSetName), 0, byte_array, 0, text.length());
+ break;
+
+ case ALIGN_RIGHT:
+ int t_offset = length - text.length();
+ System.arraycopy( text.getBytes( characterSetName), 0, byte_array, t_offset, text.length());
+ break;
+ }
+
+ return byte_array;
+ }
+
+ public static byte[] doubleFormating( Double doubleNum, String characterSetName, int fieldLength, int sizeDecimalPart) throws java.io.UnsupportedEncodingException{
+
+ int sizeWholePart = fieldLength - (sizeDecimalPart>0?( sizeDecimalPart + 1):0);
+
+ StringBuffer format = new StringBuffer( fieldLength);
+
+ for( int i=0; i 0) {
+
+ format.append( ".");
+
+ for( int i=0; i