123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356 |
- /*
- * Copyright (c) Contributors, http://opensimulator.org/
- * See CONTRIBUTORS.TXT for a full list of copyright holders.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * * Neither the name of the OpenSimulator Project nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Reflection;
- using System.Xml;
- using log4net;
- using OpenMetaverse;
- namespace OpenSim.Framework
- {
- public static class SLUtil
- {
- // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
- /// <summary>
- /// Asset types used only in OpenSim.
- /// To avoid clashing with the code numbers used in Second Life, use only negative numbers here.
- /// </summary>
- public enum OpenSimAssetType : sbyte
- {
- Material = -2
- }
-
- #region SL / file extension / content-type conversions
- /// <summary>
- /// Returns the Enum entry corresponding to the given code, regardless of whether it belongs
- /// to the AssetType or OpenSimAssetType enums.
- /// </summary>
- public static object AssetTypeFromCode(sbyte assetType)
- {
- if (Enum.IsDefined(typeof(OpenMetaverse.AssetType), assetType))
- return (OpenMetaverse.AssetType)assetType;
- else if (Enum.IsDefined(typeof(OpenSimAssetType), assetType))
- return (OpenSimAssetType)assetType;
- else
- return OpenMetaverse.AssetType.Unknown;
- }
- private class TypeMapping
- {
- private sbyte assetType;
- private InventoryType inventoryType;
- private string contentType;
- private string contentType2;
- private string extension;
- public sbyte AssetTypeCode
- {
- get { return assetType; }
- }
- public object AssetType
- {
- get { return AssetTypeFromCode(assetType); }
- }
- public InventoryType InventoryType
- {
- get { return inventoryType; }
- }
- public string ContentType
- {
- get { return contentType; }
- }
- public string ContentType2
- {
- get { return contentType2; }
- }
- public string Extension
- {
- get { return extension; }
- }
- private TypeMapping(sbyte assetType, InventoryType inventoryType, string contentType, string contentType2, string extension)
- {
- this.assetType = assetType;
- this.inventoryType = inventoryType;
- this.contentType = contentType;
- this.contentType2 = contentType2;
- this.extension = extension;
- }
- public TypeMapping(AssetType assetType, InventoryType inventoryType, string contentType, string contentType2, string extension)
- : this((sbyte)assetType, inventoryType, contentType, contentType2, extension)
- {
- }
- public TypeMapping(AssetType assetType, InventoryType inventoryType, string contentType, string extension)
- : this((sbyte)assetType, inventoryType, contentType, null, extension)
- {
- }
- public TypeMapping(OpenSimAssetType assetType, InventoryType inventoryType, string contentType, string extension)
- : this((sbyte)assetType, inventoryType, contentType, null, extension)
- {
- }
- }
- /// <summary>
- /// Maps between AssetType, InventoryType and Content-Type.
- /// Where more than one possibility exists, the first one takes precedence. E.g.:
- /// AssetType "AssetType.Texture" -> Content-Type "image-xj2c"
- /// Content-Type "image/x-j2c" -> InventoryType "InventoryType.Texture"
- /// </summary>
- private static TypeMapping[] MAPPINGS = new TypeMapping[] {
- new TypeMapping(AssetType.Unknown, InventoryType.Unknown, "application/octet-stream", "bin"),
- new TypeMapping(AssetType.Texture, InventoryType.Texture, "image/x-j2c", "image/jp2", "j2c"),
- new TypeMapping(AssetType.Texture, InventoryType.Snapshot, "image/x-j2c", "image/jp2", "j2c"),
- new TypeMapping(AssetType.TextureTGA, InventoryType.Texture, "image/tga", "tga"),
- new TypeMapping(AssetType.ImageTGA, InventoryType.Texture, "image/tga", "tga"),
- new TypeMapping(AssetType.ImageJPEG, InventoryType.Texture, "image/jpeg", "jpg"),
- new TypeMapping(AssetType.Sound, InventoryType.Sound, "audio/ogg", "application/ogg", "ogg"),
- new TypeMapping(AssetType.SoundWAV, InventoryType.Sound, "audio/x-wav", "wav"),
- new TypeMapping(AssetType.CallingCard, InventoryType.CallingCard, "application/vnd.ll.callingcard", "application/x-metaverse-callingcard", "callingcard"),
- new TypeMapping(AssetType.Landmark, InventoryType.Landmark, "application/vnd.ll.landmark", "application/x-metaverse-landmark", "landmark"),
- new TypeMapping(AssetType.Clothing, InventoryType.Wearable, "application/vnd.ll.clothing", "application/x-metaverse-clothing", "clothing"),
- new TypeMapping(AssetType.Object, InventoryType.Object, "application/vnd.ll.primitive", "application/x-metaverse-primitive", "primitive"),
- new TypeMapping(AssetType.Object, InventoryType.Attachment, "application/vnd.ll.primitive", "application/x-metaverse-primitive", "primitive"),
- new TypeMapping(AssetType.Notecard, InventoryType.Notecard, "application/vnd.ll.notecard", "application/x-metaverse-notecard", "notecard"),
- new TypeMapping(AssetType.Folder, InventoryType.Folder, "application/vnd.ll.folder", "folder"),
- new TypeMapping(AssetType.RootFolder, InventoryType.RootCategory, "application/vnd.ll.rootfolder", "rootfolder"),
- new TypeMapping(AssetType.LSLText, InventoryType.LSL, "application/vnd.ll.lsltext", "application/x-metaverse-lsl", "lsl"),
- new TypeMapping(AssetType.LSLBytecode, InventoryType.LSL, "application/vnd.ll.lslbyte", "application/x-metaverse-lso", "lso"),
- new TypeMapping(AssetType.Bodypart, InventoryType.Wearable, "application/vnd.ll.bodypart", "application/x-metaverse-bodypart", "bodypart"),
- new TypeMapping(AssetType.TrashFolder, InventoryType.Folder, "application/vnd.ll.trashfolder", "trashfolder"),
- new TypeMapping(AssetType.SnapshotFolder, InventoryType.Folder, "application/vnd.ll.snapshotfolder", "snapshotfolder"),
- new TypeMapping(AssetType.LostAndFoundFolder, InventoryType.Folder, "application/vnd.ll.lostandfoundfolder", "lostandfoundfolder"),
- new TypeMapping(AssetType.Animation, InventoryType.Animation, "application/vnd.ll.animation", "application/x-metaverse-animation", "animation"),
- new TypeMapping(AssetType.Gesture, InventoryType.Gesture, "application/vnd.ll.gesture", "application/x-metaverse-gesture", "gesture"),
- new TypeMapping(AssetType.Simstate, InventoryType.Snapshot, "application/x-metaverse-simstate", "simstate"),
- new TypeMapping(AssetType.FavoriteFolder, InventoryType.Unknown, "application/vnd.ll.favoritefolder", "favoritefolder"),
- new TypeMapping(AssetType.Link, InventoryType.Unknown, "application/vnd.ll.link", "link"),
- new TypeMapping(AssetType.LinkFolder, InventoryType.Unknown, "application/vnd.ll.linkfolder", "linkfolder"),
- new TypeMapping(AssetType.CurrentOutfitFolder, InventoryType.Unknown, "application/vnd.ll.currentoutfitfolder", "currentoutfitfolder"),
- new TypeMapping(AssetType.OutfitFolder, InventoryType.Unknown, "application/vnd.ll.outfitfolder", "outfitfolder"),
- new TypeMapping(AssetType.MyOutfitsFolder, InventoryType.Unknown, "application/vnd.ll.myoutfitsfolder", "myoutfitsfolder"),
- new TypeMapping(AssetType.Mesh, InventoryType.Mesh, "application/vnd.ll.mesh", "llm"),
-
- new TypeMapping(OpenSimAssetType.Material, InventoryType.Unknown, "application/llsd+xml", "material")
- };
- private static Dictionary<sbyte, string> asset2Content;
- private static Dictionary<sbyte, string> asset2Extension;
- private static Dictionary<InventoryType, string> inventory2Content;
- private static Dictionary<string, sbyte> content2Asset;
- private static Dictionary<string, InventoryType> content2Inventory;
- static SLUtil()
- {
- asset2Content = new Dictionary<sbyte, string>();
- asset2Extension = new Dictionary<sbyte, string>();
- inventory2Content = new Dictionary<InventoryType, string>();
- content2Asset = new Dictionary<string, sbyte>();
- content2Inventory = new Dictionary<string, InventoryType>();
-
- foreach (TypeMapping mapping in MAPPINGS)
- {
- sbyte assetType = mapping.AssetTypeCode;
- if (!asset2Content.ContainsKey(assetType))
- asset2Content.Add(assetType, mapping.ContentType);
- if (!asset2Extension.ContainsKey(assetType))
- asset2Extension.Add(assetType, mapping.Extension);
- if (!inventory2Content.ContainsKey(mapping.InventoryType))
- inventory2Content.Add(mapping.InventoryType, mapping.ContentType);
- if (!content2Asset.ContainsKey(mapping.ContentType))
- content2Asset.Add(mapping.ContentType, assetType);
- if (!content2Inventory.ContainsKey(mapping.ContentType))
- content2Inventory.Add(mapping.ContentType, mapping.InventoryType);
- if (mapping.ContentType2 != null)
- {
- if (!content2Asset.ContainsKey(mapping.ContentType2))
- content2Asset.Add(mapping.ContentType2, assetType);
- if (!content2Inventory.ContainsKey(mapping.ContentType2))
- content2Inventory.Add(mapping.ContentType2, mapping.InventoryType);
- }
- }
- }
-
- public static string SLAssetTypeToContentType(int assetType)
- {
- string contentType;
- if (!asset2Content.TryGetValue((sbyte)assetType, out contentType))
- contentType = asset2Content[(sbyte)AssetType.Unknown];
- return contentType;
- }
- public static string SLInvTypeToContentType(int invType)
- {
- string contentType;
- if (!inventory2Content.TryGetValue((InventoryType)invType, out contentType))
- contentType = inventory2Content[InventoryType.Unknown];
- return contentType;
- }
- public static sbyte ContentTypeToSLAssetType(string contentType)
- {
- sbyte assetType;
- if (!content2Asset.TryGetValue(contentType, out assetType))
- assetType = (sbyte)AssetType.Unknown;
- return (sbyte)assetType;
- }
- public static sbyte ContentTypeToSLInvType(string contentType)
- {
- InventoryType invType;
- if (!content2Inventory.TryGetValue(contentType, out invType))
- invType = InventoryType.Unknown;
- return (sbyte)invType;
- }
- public static string SLAssetTypeToExtension(int assetType)
- {
- string extension;
- if (!asset2Extension.TryGetValue((sbyte)assetType, out extension))
- extension = asset2Extension[(sbyte)AssetType.Unknown];
- return extension;
- }
- #endregion SL / file extension / content-type conversions
- /// <summary>
- /// Parse a notecard in Linden format to a string of ordinary text.
- /// </summary>
- /// <param name="rawInput"></param>
- /// <returns></returns>
- public static string ParseNotecardToString(string rawInput)
- {
- string[] output = ParseNotecardToList(rawInput).ToArray();
- // foreach (string line in output)
- // m_log.DebugFormat("[PARSE NOTECARD]: ParseNotecardToString got line {0}", line);
-
- return string.Join("\n", output);
- }
-
- /// <summary>
- /// Parse a notecard in Linden format to a list of ordinary lines.
- /// </summary>
- /// <param name="rawInput"></param>
- /// <returns></returns>
- public static List<string> ParseNotecardToList(string rawInput)
- {
- string[] input;
- int idx = 0;
- int level = 0;
- List<string> output = new List<string>();
- string[] words;
- //The Linden format always ends with a } after the input data.
- //Strip off trailing } so there is nothing after the input data.
- int i = rawInput.LastIndexOf("}");
- rawInput = rawInput.Remove(i, rawInput.Length-i);
- input = rawInput.Replace("\r", "").Split('\n');
- while (idx < input.Length)
- {
- if (input[idx] == "{")
- {
- level++;
- idx++;
- continue;
- }
- if (input[idx]== "}")
- {
- level--;
- idx++;
- continue;
- }
- switch (level)
- {
- case 0:
- words = input[idx].Split(' '); // Linden text ver
- // Notecards are created *really* empty. Treat that as "no text" (just like after saving an empty notecard)
- if (words.Length < 3)
- return output;
- int version = int.Parse(words[3]);
- if (version != 2)
- return output;
- break;
- case 1:
- words = input[idx].Split(' ');
- if (words[0] == "LLEmbeddedItems")
- break;
- if (words[0] == "Text")
- {
- idx++; //Now points to first line of notecard text
- //Number of lines in notecard.
- int lines = input.Length - idx;
- int line = 0;
- while (line < lines)
- {
- // m_log.DebugFormat("[PARSE NOTECARD]: Adding line {0}", input[idx]);
- output.Add(input[idx]);
- idx++;
- line++;
- }
- return output;
- }
- break;
- case 2:
- words = input[idx].Split(' '); // count
- if (words[0] == "count")
- {
- int c = int.Parse(words[1]);
- if (c > 0)
- return output;
- break;
- }
- break;
- }
- idx++;
- }
-
- return output;
- }
- }
- }
|