Author: toad
Date: 2005-10-28 19:24:06 +0000 (Fri, 28 Oct 2005)
New Revision: 7462

Modified:
   trunk/freenet/src/freenet/client/ArchiveManager.java
   trunk/freenet/src/freenet/client/ClientMetadata.java
   trunk/freenet/src/freenet/client/DefaultMIMETypes.java
   trunk/freenet/src/freenet/client/Metadata.java
   trunk/freenet/src/freenet/keys/FreenetURI.java
Log:
Various.

Modified: trunk/freenet/src/freenet/client/ArchiveManager.java
===================================================================
--- trunk/freenet/src/freenet/client/ArchiveManager.java        2005-10-28 
15:12:45 UTC (rev 7461)
+++ trunk/freenet/src/freenet/client/ArchiveManager.java        2005-10-28 
19:24:06 UTC (rev 7462)
@@ -5,7 +5,9 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipInputStream;
 
@@ -216,8 +218,9 @@
         * @param ctx The context object.
         * @param key The key from which the archive we are unpacking was 
fetched.
         * @param names Set of names in the archive.
+        * @throws ArchiveFailureException 
         */
-       private void generateMetadata(ArchiveStoreContext ctx, FreenetURI key, 
HashSet names) {
+       private void generateMetadata(ArchiveStoreContext ctx, FreenetURI key, 
HashSet names) throws ArchiveFailureException {
                /* What we have to do is to:
                 * - Construct a filesystem tree of the names.
                 * - Turn each level of the tree into a Metadata object, 
including those below it, with
@@ -225,9 +228,50 @@
                 * - Turn the master Metadata object into binary metadata, with 
all its subsidiaries.
                 * - Create a .metadata entry containing this data.
                 */
-               
-               // TODO implement!
+               // Root directory.
+               // String -> either itself, or another HashMap
+               HashMap dir = new HashMap();
+               Iterator i = names.iterator();
+               while(i.hasNext()) {
+                       String name = (String) i.next();
+                       addToDirectory(dir, name, "");
+               }
+               Metadata metadata = new Metadata(dir);
+               TempStoreElement element = makeTempStoreBucket(-1);
+               OutputStream os = element.bucket.getOutputStream();
+               metadata.writeTo(os);
+               os.close();
+               addStoreElement(ctx, key, ".metadata", element);
        }
+       
+       private void addToDirectory(HashMap dir, String name, String prefix) 
throws ArchiveFailureException {
+               int x = name.indexOf('/');
+               if(x < 0) {
+                       if(dir.containsKey(name)) {
+                               throw new ArchiveFailureException("Invalid 
archive: contains "+prefix+name+" twice");
+                       }
+                       dir.put(name, name);
+               } else {
+                       String before = name.substring(0, x);
+                       String after;
+                       if(x == name.length()-1) {
+                               // Last char
+                               after = "";
+                       } else
+                               after = name.substring(x+1, name.length());
+                       Object o = (Object) dir.get(before);
+                       HashMap map;
+                       if(o == null) {
+                               map = new HashMap();
+                               dir.put(before, map);
+                       }
+                       if(o instanceof String) {
+                               throw new ArchiveFailureException("Invalid 
archive: contains "+name+" as both file and dir");
+                       }
+                       map = (HashMap) o;
+                       addToDirectory(map, after, prefix + before + "/");
+               }
+       }
 
        private void addErrorElement(ArchiveStoreContext ctx, FreenetURI key, 
String name, String error) {
                ErrorArchiveStoreItem element = new ErrorArchiveStoreItem(ctx, 
key, name, error);

Modified: trunk/freenet/src/freenet/client/ClientMetadata.java
===================================================================
--- trunk/freenet/src/freenet/client/ClientMetadata.java        2005-10-28 
15:12:45 UTC (rev 7461)
+++ trunk/freenet/src/freenet/client/ClientMetadata.java        2005-10-28 
19:24:06 UTC (rev 7462)
@@ -5,9 +5,6 @@
  */
 public class ClientMetadata {
        
-       /** Default MIME type - what to set it to if we don't know any better */
-       public static final String DEFAULT_MIME_TYPE = 
"application/octet-stream";
-       
        /** The document MIME type */
        private String mimeType;
 
@@ -22,7 +19,7 @@
        
        public String getMIMEType() {
                if(mimeType == null || mimeType.length() == 0)
-                       return DEFAULT_MIME_TYPE;
+                       return DefaultMIMETypes.DEFAULT_MIME_TYPE;
                return mimeType;
        }
 

Modified: trunk/freenet/src/freenet/client/DefaultMIMETypes.java
===================================================================
--- trunk/freenet/src/freenet/client/DefaultMIMETypes.java      2005-10-28 
15:12:45 UTC (rev 7461)
+++ trunk/freenet/src/freenet/client/DefaultMIMETypes.java      2005-10-28 
19:24:06 UTC (rev 7462)
@@ -8,6 +8,9 @@
  */
 class DefaultMIMETypes {
        
+       /** Default MIME type - what to set it to if we don't know any better */
+       public static final String DEFAULT_MIME_TYPE = 
"application/octet-stream";
+       
        private static Vector mimeTypesByNumber = new Vector();
        
        private static HashMap mimeTypesByName = new HashMap();
@@ -26,7 +29,7 @@
                Short t = new Short(type);
                if(extensions != null)
                        for(int i=0;i<extensions.length;i++)
-                               mimeTypesByExtension.put(extensions[i], t);
+                               
mimeTypesByExtension.put(extensions[i].toLowerCase(), t);
        }
        
        protected static synchronized void addMIMEType(short number, String 
type, String extensions) {
@@ -665,4 +668,16 @@
                addMIMEType((short)611, "x-conference/x-cooltalk", "ice");
                addMIMEType((short)612, "x-world/x-vrml", "vrm vrml wrl");
        }
+       
+       /** Guess a MIME type from a filename */
+       public static String guessMIMEType(String arg) {
+               int x = arg.indexOf('.');
+               if(x == -1 || x == arg.length()-1)
+                       return DEFAULT_MIME_TYPE;
+               String ext = arg.substring(x+1).toLowerCase();
+               Short mimeIndexOb = (Short) mimeTypesByExtension.get(ext);
+               if(mimeIndexOb != null) {
+                       return (String) 
mimeTypesByNumber.get(mimeIndexOb.intValue());
+               } else return DEFAULT_MIME_TYPE;
+       }
 }

Modified: trunk/freenet/src/freenet/client/Metadata.java
===================================================================
--- trunk/freenet/src/freenet/client/Metadata.java      2005-10-28 15:12:45 UTC 
(rev 7461)
+++ trunk/freenet/src/freenet/client/Metadata.java      2005-10-28 19:24:06 UTC 
(rev 7462)
@@ -1,10 +1,12 @@
 package freenet.client;
 
 import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.DataInputStream;
 import java.io.IOException;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 
 import freenet.keys.ClientCHK;
 import freenet.keys.ClientKey;
@@ -104,7 +106,7 @@
                }
                
                if(noMIME) {
-                       mimeType = ClientMetadata.DEFAULT_MIME_TYPE;
+                       mimeType = DefaultMIMETypes.DEFAULT_MIME_TYPE;
                } else {
                        if(compressedMIME) {
                                short x = dis.readShort();
@@ -220,17 +222,67 @@
        }
        
        /**
+        * Create a Metadata object for an archive which does not have its own
+        * metadata.
+        * @param dir A map of names (string) to either files (same string) or
+        * directories (more HashMap's)
+        */
+       Metadata(HashMap dir) {
+               // Simple manifest - contains actual redirects.
+               // Not zip manifest, which is basically a redirect.
+               documentType = SIMPLE_MANIFEST;
+               noMIME = true;
+               mimeType = null;
+               clientMetadata = new ClientMetadata(null);
+               manifestEntries = new HashMap();
+               int count = 0;
+               for(Iterator i = dir.keySet().iterator();i.hasNext();) {
+                       String key = (String) i.next();
+                       count++;
+                       Object o = dir.get(key);
+                       Metadata target;
+                       if(o instanceof String) {
+                               // Zip internal redirect
+                               target = new Metadata(ZIP_INTERNAL_REDIRECT, 
key);
+                       } else if(o instanceof HashMap) {
+                               target = new Metadata((HashMap)o);
+                       } else throw new IllegalArgumentException("Not String 
nor HashMap: "+o);
+                       byte[] data = target.writeToByteArray();
+                       manifestEntries.put(key, data);
+               }
+               manifestEntryCount = count;
+       }
+
+       public Metadata(byte docType, String arg) {
+               if(docType == ZIP_INTERNAL_REDIRECT) {
+                       documentType = docType;
+                       // Determine MIME type
+                       mimeType = DefaultMIMETypes.guessMIMEType(arg);
+                       clientMetadata = new ClientMetadata(mimeType);
+                       nameInArchive = arg;
+               } else
+                       throw new IllegalArgumentException();
+       }
+
+       private byte[] writeToByteArray() {
+               ByteArrayOutputStream baos = new ByteArrayOutputStream();
+               writeTo(baos);
+               return baos.toByteArray();
+       }
+
+       /**
         * Read a key using the current settings.
+        * @throws IOException 
         */
-       private FreenetURI readKey(DataInputStream dis) {
+       private FreenetURI readKey(DataInputStream dis) throws IOException {
                // Read URL
                if(fullKeys) {
-                       int length = (dis.readByte() & 0xff);
+                       int length = dis.readShort();
                        byte[] buf = new byte[length];
                        dis.readFully(buf);
-                       simpleRedirectKey = FreenetURI.fromFullBinaryKey(buf);
+                       return FreenetURI.fromFullBinaryKey(buf);
                } else {
-                       simpleRedirectKey = 
ClientCHK.readRawBinaryKey(dis).getURI();
+                       return ClientCHK.readRawBinaryKey(dis).getURI();
                }
        }
 

Modified: trunk/freenet/src/freenet/keys/FreenetURI.java
===================================================================
--- trunk/freenet/src/freenet/keys/FreenetURI.java      2005-10-28 15:12:45 UTC 
(rev 7461)
+++ trunk/freenet/src/freenet/keys/FreenetURI.java      2005-10-28 19:24:06 UTC 
(rev 7462)
@@ -1,5 +1,8 @@
 package freenet.keys;
 
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
 import java.net.MalformedURLException;
 import java.util.LinkedList;
 import java.util.StringTokenizer;
@@ -10,10 +13,13 @@
 import freenet.support.IllegalBase64Exception;
 
 /**
+ * Note that the metadata pairs below are not presently supported. They are 
supported
+ * by the old (0.5) code however.
+ * 
  * FreenetURI handles parsing and creation of the Freenet URI format, defined
  * as follows:
  * <p>
- * <code>freenet:[EMAIL 
PROTECTED],CryptoKey][,n1=v1,n2=v2,...][/docname][//metastring]</code>
+ * <code>freenet:[EMAIL 
PROTECTED],CryptoKey[,n1=v1,n2=v2,...][/docname][//metastring]</code>
  * </p>
  * <p>
  * where KeyType is the TLA of the key (currently SVK, SSK, KSK, or CHK). If
@@ -391,4 +397,45 @@
                }
                return l;
        }
+       
+       static final byte CHK = 1;
+       static final byte SSK = 2;
+       
+       public static FreenetURI fromFullBinaryKey(byte[] buf) throws 
IOException {
+               ByteArrayInputStream bais = new ByteArrayInputStream(buf);
+               DataInputStream dis = new DataInputStream(bais);
+               return fromFullBinaryKey(dis);
+       }
+       
+       public static FreenetURI fromFullBinaryKey(DataInputStream dis) throws 
IOException {
+               int x = 0;
+               byte type = dis.readByte();
+               String keyType;
+               if(type == CHK)
+                       keyType = "CHK";
+               else if(type == SSK)
+                       keyType = "SSK";
+               else 
+                       throw new MalformedURLException("Unrecognized type 
"+type);
+               // routingKey is a hash, so is exactly 32 bytes
+               byte[] routingKey = new byte[32];
+               dis.readFully(routingKey);
+               // cryptoKey is a 256 bit AES key, so likewise
+               byte[] cryptoKey = new byte[32];
+               dis.readFully(cryptoKey);
+               // Number of bytes of extra depends on key type
+               int extraLen;
+               if(type == CHK)
+                       extraLen = ClientCHK.EXTRA_LENGTH;
+               else
+                       throw new UnsupportedOperationException("SSKs not 
implemented yet!");
+                       //extraLen = ClientSSK.EXTRA_LENGTH;
+               byte[] extra = new byte[extraLen];
+               dis.readFully(extra);
+               String docName = dis.readUTF();
+               int count = dis.readByte() & 0xff;
+               String[] metaStrings = new String[count];
+               for(int i=0;i<metaStrings.length;i++) metaStrings[i] = 
dis.readUTF();
+               return new FreenetURI(keyType, docName, metaStrings, 
routingKey, cryptoKey, extra);
+       }
 }

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

Reply via email to