Author: toad
Date: 2005-10-28 20:51:43 +0000 (Fri, 28 Oct 2005)
New Revision: 7463

Modified:
   trunk/freenet/src/freenet/client/ArchiveManager.java
   trunk/freenet/src/freenet/client/Metadata.java
   trunk/freenet/src/freenet/keys/ClientCHK.java
   trunk/freenet/src/freenet/keys/FreenetURI.java
Log:
It compiles.
But more work to do to get something useful.

Modified: trunk/freenet/src/freenet/client/ArchiveManager.java
===================================================================
--- trunk/freenet/src/freenet/client/ArchiveManager.java        2005-10-28 
19:24:06 UTC (rev 7462)
+++ trunk/freenet/src/freenet/client/ArchiveManager.java        2005-10-28 
20:51:43 UTC (rev 7463)
@@ -1,5 +1,6 @@
 package freenet.client;
 
+import java.io.DataOutputStream;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
@@ -238,9 +239,13 @@
                }
                Metadata metadata = new Metadata(dir);
                TempStoreElement element = makeTempStoreBucket(-1);
-               OutputStream os = element.bucket.getOutputStream();
-               metadata.writeTo(os);
-               os.close();
+               try {
+                       OutputStream os = element.bucket.getOutputStream();
+                       metadata.writeTo(new DataOutputStream(os));
+                       os.close();
+               } catch (IOException e) {
+                       throw new ArchiveFailureException("Failed to create 
metadata: "+e, e);
+               }
                addStoreElement(ctx, key, ".metadata", element);
        }
        

Modified: trunk/freenet/src/freenet/client/Metadata.java
===================================================================
--- trunk/freenet/src/freenet/client/Metadata.java      2005-10-28 19:24:06 UTC 
(rev 7462)
+++ trunk/freenet/src/freenet/client/Metadata.java      2005-10-28 20:51:43 UTC 
(rev 7463)
@@ -3,7 +3,9 @@
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.DataInputStream;
+import java.io.DataOutputStream;
 import java.io.IOException;
+import java.io.OutputStream;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -125,8 +127,8 @@
                                int len = l & 0xff; // positive
                                byte[] toRead = new byte[len];
                                dis.readFully(toRead);
-                               // MIME types are all ISO-8859-1, right?
-                               mimeType = new String(toRead);
+                               // Use UTF-8 for everything, for simplicity
+                               mimeType = new String(toRead, "UTF-8");
                        }
                }
                
@@ -143,6 +145,7 @@
                                dis.readFully(buf);
                                Logger.normal(this, "Ignoring type "+type+" 
extra-client-metadata field of "+length+" bytes");
                        }
+                       extraMetadata = false; // can't parse, can't write
                }
                
                clientMetadata = new ClientMetadata(mimeType);
@@ -199,11 +202,11 @@
                        // Don't validate, just keep the data; parse later
                        
                        for(int i=0;i<manifestEntryCount;i++) {
-                               int nameLength = (dis.readByte() & 0xff);
+                               short nameLength = dis.readShort();
                                byte[] buf = new byte[nameLength];
                                dis.readFully(buf);
                                String name = new String(buf, "UTF-8");
-                               int len = dis.readInt();
+                               short len = dis.readShort();
                                if(len < 0)
                                        throw new 
MetadataParseException("Invalid manifest entry size: "+len);
                                if(len > length)
@@ -215,9 +218,9 @@
                }
                
                if(documentType == ZIP_INTERNAL_REDIRECT) {
-                       int len = (dis.readByte() & 0xff);
+                       int len = dis.readShort();
                        byte[] buf = new byte[len];
-                       nameInArchive = new String(buf);
+                       nameInArchive = new String(buf, "UTF-8");
                }
        }
        
@@ -257,35 +260,65 @@
                if(docType == ZIP_INTERNAL_REDIRECT) {
                        documentType = docType;
                        // Determine MIME type
-                       mimeType = DefaultMIMETypes.guessMIMEType(arg);
+                       setMIMEType(DefaultMIMETypes.guessMIMEType(arg));
                        clientMetadata = new ClientMetadata(mimeType);
                        nameInArchive = arg;
                } else
                        throw new IllegalArgumentException();
        }
 
+       private void setMIMEType(String type) {
+               short s = DefaultMIMETypes.byName(type);
+               if(s >= 0) {
+                       compressedMIME = true;
+                       compressedMIMEValue = s;
+               } else {
+                       compressedMIME = false;
+               }
+               mimeType = type;
+       }
+
        private byte[] writeToByteArray() {
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
-               writeTo(baos);
+               DataOutputStream dos = new DataOutputStream(baos);
+               try {
+                       writeTo(dos);
+               } catch (IOException e) {
+                       throw new Error("Could not write to byte array: "+e, e);
+               }
                return baos.toByteArray();
        }
 
        /**
         * Read a key using the current settings.
         * @throws IOException 
+        * @throws MalformedURLException If the key could not be read due to an 
error in parsing the key.
+        * REDFLAG: May want to recover from these in future, hence the short 
length.
         */
        private FreenetURI readKey(DataInputStream dis) throws IOException {
                // Read URL
                if(fullKeys) {
-                       int length = dis.readShort();
-                       byte[] buf = new byte[length];
-                       dis.readFully(buf);
-                       return FreenetURI.fromFullBinaryKey(buf);
+                       return FreenetURI.readFullBinaryKeyWithLength(dis);
                } else {
                        return ClientCHK.readRawBinaryKey(dis).getURI();
                }
        }
 
+       /**
+        * Write a key using the current settings.
+        * @throws IOException 
+        * @throws MalformedURLException If an error in the key itself 
prevented it from being written.
+        */
+       private void writeKey(DataOutputStream dos, FreenetURI freenetURI) 
throws IOException {
+               if(fullKeys) {
+                       freenetURI.writeFullBinaryKeyWithLength(dos);
+               } else {
+                       ClientKey key = ClientKey.getBaseKey(freenetURI);
+                       if(key instanceof ClientCHK) {
+                               ((ClientCHK)key).writeRawBinaryKey(dos);
+                       } else throw new IllegalArgumentException("Full keys 
must be enabled to write non-CHKs");
+               }
+       }
        // Actual parsed data
        
        // document type
@@ -301,8 +334,8 @@
        boolean splitfile;
        /** Is a DBR */
        boolean dbr;
-       /** No MIME type */
-       boolean noMIME;
+       /** No MIME type; on by default as not all doctypes have MIME */
+       boolean noMIME = true;
        /** Compressed MIME type */
        boolean compressedMIME;
        /** Has extra client-metadata */
@@ -329,7 +362,7 @@
        
        /** Compressed splitfile codec */
        short compressionCodec;
-       static final short COMPRESS_GZIP = 0;
+       static final short COMPRESS_GZIP = 0; // for future use
        static final short COMPRESS_BZIP2 = 1; // FIXME for future use
        
        /** The length of the splitfile */
@@ -464,4 +497,99 @@
        public void setSimpleRedirect() {
                documentType = SIMPLE_REDIRECT;
        }
+       
+       /** Write the metadata as binary. 
+        * @throws IOException */
+       public void writeTo(DataOutputStream dos) throws IOException {
+               dos.writeLong(FREENET_METADATA_MAGIC);
+               dos.writeShort(0); // version
+               dos.writeByte(documentType);
+               if(documentType == SIMPLE_REDIRECT || documentType == 
MULTI_LEVEL_METADATA
+                               || documentType == ZIP_MANIFEST) {
+                       short flags = 0;
+                       if(splitfile) flags |= FLAGS_SPLITFILE;
+                       if(dbr) flags |= FLAGS_DBR;
+                       if(noMIME) flags |= FLAGS_NO_MIME;
+                       if(compressedMIME) flags |= FLAGS_COMPRESSED_MIME;
+                       if(extraMetadata) flags |= FLAGS_EXTRA_METADATA;
+                       if(fullKeys) flags |= FLAGS_FULL_KEYS;
+                       if(splitUseLengths) flags |= FLAGS_SPLIT_USE_LENGTHS;
+                       if(compressed) flags |= FLAGS_COMPRESSED;
+               }
+               
+               if(documentType == ZIP_MANIFEST) {
+                       dos.writeShort(archiveType);
+               }
+               
+               if(splitfile) {
+                       dos.writeLong(dataLength);
+               }
+               
+               if(compressed) {
+                       dos.writeShort(compressionCodec);
+                       dos.writeLong(decompressedLength);
+               }
+               
+               if(!noMIME) {
+                       if(compressedMIME) {
+                               int x = compressedMIMEValue;
+                               if(hasCompressedMIMEParams) x |= 32768;
+                               dos.writeShort((short)x);
+                               if(hasCompressedMIMEParams)
+                                       dos.writeShort(compressedMIMEParams);
+                       } else {
+                               byte[] data = mimeType.getBytes("UTF-8");
+                               if(data.length > 255) throw new Error("MIME 
type too long: "+data.length+" bytes: "+mimeType);
+                               dos.writeByte((byte)data.length);
+                               dos.write(data);
+                       }
+               }
+               
+               if(dbr)
+                       throw new UnsupportedOperationException("No DBR support 
yet");
+               
+               if(extraMetadata)
+                       throw new UnsupportedOperationException("No extra 
metadata support yet");
+               
+               if((!splitfile) && documentType == SIMPLE_REDIRECT || 
documentType == ZIP_MANIFEST) {
+                       writeKey(dos, simpleRedirectKey);
+               } else if(splitfile) {
+                       dos.writeShort(splitfileAlgorithm);
+                       if(splitfileParams != null) {
+                               dos.writeInt(splitfileParams.length);
+                               dos.write(splitfileParams);
+                       } else
+                               dos.writeInt(0);
+                       
+                       dos.writeInt(splitfileBlocks);
+                       dos.writeInt(splitfileCheckBlocks);
+                       for(int i=0;i<splitfileBlocks;i++)
+                               writeKey(dos, splitfileDataKeys[i]);
+                       for(int i=0;i<splitfileCheckBlocks;i++)
+                               writeKey(dos, splitfileCheckKeys[i]);
+               }
+               
+               if(documentType == SIMPLE_MANIFEST) {
+                       dos.writeInt(manifestEntryCount);
+                       for(Iterator 
i=manifestEntries.keySet().iterator();i.hasNext();) {
+                               String name = (String) i.next();
+                               byte[] nameData = name.getBytes("UTF-8");
+                               if(nameData.length > Short.MAX_VALUE) throw new 
IllegalArgumentException("Manifest name too long");
+                               dos.writeShort(nameData.length);
+                               dos.write(nameData);
+                               byte[] data = (byte[]) 
manifestEntries.get(name);
+                               if(data.length > Short.MAX_VALUE) throw new 
IllegalArgumentException("Manifest data too long");
+                               dos.writeShort(data.length);
+                               dos.write(data);
+                       }
+               }
+               
+               if(documentType == ZIP_INTERNAL_REDIRECT) {
+                       byte[] data = nameInArchive.getBytes("UTF-8");
+                       if(data.length > Short.MAX_VALUE) throw new 
IllegalArgumentException("Zip internal redirect name too long");
+                       dos.writeShort(data.length);
+                       dos.write(data);
+               }
+       }
+
 }

Modified: trunk/freenet/src/freenet/keys/ClientCHK.java
===================================================================
--- trunk/freenet/src/freenet/keys/ClientCHK.java       2005-10-28 19:24:06 UTC 
(rev 7462)
+++ trunk/freenet/src/freenet/keys/ClientCHK.java       2005-10-28 20:51:43 UTC 
(rev 7463)
@@ -1,6 +1,7 @@
 package freenet.keys;
 
 import java.io.DataInputStream;
+import java.io.DataOutputStream;
 import java.io.IOException;
 import java.net.MalformedURLException;
 
@@ -72,6 +73,19 @@
                dis.readFully(cryptoKey);
        }
 
+       /**
+        * Write an ultra-compact representation.
+        * @throws IOException If a write failed.
+        */
+       public void writeRawBinaryKey(DataOutputStream dos) throws IOException {
+               byte[] extra = new byte[EXTRA_LENGTH];
+               extra[0] = (byte) (cryptoAlgorithm >> 8);
+               extra[1] = (byte) cryptoAlgorithm;
+               extra[2] = (byte) ((compressed ? 1 : 0) + (controlDocument ? 2 
: 0));
+               dos.write(extra);
+               dos.write(routingKey);
+               dos.write(cryptoKey);
+       }
     
     byte[] routingKey;
     byte[] cryptoKey;

Modified: trunk/freenet/src/freenet/keys/FreenetURI.java
===================================================================
--- trunk/freenet/src/freenet/keys/FreenetURI.java      2005-10-28 19:24:06 UTC 
(rev 7462)
+++ trunk/freenet/src/freenet/keys/FreenetURI.java      2005-10-28 20:51:43 UTC 
(rev 7463)
@@ -1,7 +1,9 @@
 package freenet.keys;
 
 import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.DataInputStream;
+import java.io.DataOutputStream;
 import java.io.IOException;
 import java.net.MalformedURLException;
 import java.util.LinkedList;
@@ -401,13 +403,20 @@
        static final byte CHK = 1;
        static final byte SSK = 2;
        
+       public static FreenetURI readFullBinaryKeyWithLength(DataInputStream 
dis) throws IOException {
+               int len = dis.readShort() & 0xffff;
+               byte[] buf = new byte[len];
+               dis.readFully(buf);
+               return fromFullBinaryKey(buf);
+       }
+       
        public static FreenetURI fromFullBinaryKey(byte[] buf) throws 
IOException {
                ByteArrayInputStream bais = new ByteArrayInputStream(buf);
                DataInputStream dis = new DataInputStream(bais);
-               return fromFullBinaryKey(dis);
+               return readFullBinaryKey(dis);
        }
        
-       public static FreenetURI fromFullBinaryKey(DataInputStream dis) throws 
IOException {
+       public static FreenetURI readFullBinaryKey(DataInputStream dis) throws 
IOException {
                int x = 0;
                byte type = dis.readByte();
                String keyType;
@@ -438,4 +447,55 @@
                for(int i=0;i<metaStrings.length;i++) metaStrings[i] = 
dis.readUTF();
                return new FreenetURI(keyType, docName, metaStrings, 
routingKey, cryptoKey, extra);
        }
+
+       /**
+        * Write a binary representation of this URI, with a short length, so 
it can be passed over if necessary.
+        * @param dos The stream to write to.
+        * @throws MalformedURLException If the key could not be written 
because of inconsistencies or other
+        * problems in the key itself.
+        * @throws IOException If an error occurred while writing the key.
+        */
+       public void writeFullBinaryKeyWithLength(DataOutputStream dos) throws 
IOException {
+               ByteArrayOutputStream baos = new ByteArrayOutputStream();
+               DataOutputStream ndos = new DataOutputStream(baos);
+               writeFullBinaryKey(ndos);
+               ndos.close();
+               byte[] data = baos.toByteArray();
+               if(data.length > 0xffff)
+                       throw new MalformedURLException("Full key too long: 
"+data.length+" - "+this);
+               dos.writeShort((short)data.length);
+               dos.write(data);
+       }
+
+       /**
+        * Write a binary representation of this URI.
+        * @param dos The stream to write to.
+        * @throws MalformedURLException If the key could not be written 
because of inconsistencies or other
+        * problems in the key itself.
+        * @throws IOException If an error occurred while writing the key.
+        */
+       private void writeFullBinaryKey(DataOutputStream dos) throws 
IOException {
+               if(keyType.equals("CHK")) {
+                       dos.writeByte(CHK);
+               } else if(keyType.equals("SSK")) {
+                       dos.writeByte(SSK);
+               } else
+                       throw new MalformedURLException("Cannot write key of 
type "+keyType+" - do not know how");
+               if(routingKey.length != 32)
+                       throw new MalformedURLException("Routing key must be of 
length 32");
+               if(cryptoKey.length != 32)
+                       throw new MalformedURLException("Crypto key must be of 
length 32");
+               if(keyType.equals("CHK") && extra.length != 
ClientCHK.EXTRA_LENGTH)
+                       throw new MalformedURLException("Wrong number of extra 
bytes for CHK");
+               if(keyType.equals("SSK"))
+                       throw new UnsupportedOperationException("SSK support 
not yet implemented");
+               dos.write(extra);
+               dos.writeUTF(docName);
+               if(metaStr != null) {
+                       dos.writeInt(metaStr.length);
+                       for(int i=0;i<metaStr.length;i++)
+                               dos.writeUTF(metaStr[i]);
+               } else
+                       dos.writeInt(0);
+       }
 }

_______________________________________________
cvs mailing list
[email protected]
http://emu.freenetproject.org/cgi-bin/mailman/listinfo/cvs

Reply via email to