├── .travis.yml
├── LICENSE
├── README.md
├── demo.cc
├── tests.cxx
├── unify.cpp
└── unify.hpp
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: cpp
2 | sudo: required
3 |
4 | compiler:
5 | - clang
6 | - gcc
7 |
8 | install:
9 | - wget --quiet -O - https://raw.githubusercontent.com/r-lyeh/depot/master/travis.pre.sh | bash -x
10 |
11 | script:
12 | - wget --quiet -O - https://raw.githubusercontent.com/r-lyeh/depot/master/travis.build.sh | bash -x
13 | - wget --quiet -O - https://raw.githubusercontent.com/r-lyeh/depot/master/travis.run.sh | bash -x
14 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2015 r-lyeh (https://github.com/r-lyeh)
2 |
3 | This software is provided 'as-is', without any express or implied
4 | warranty. In no event will the authors be held liable for any damages
5 | arising from the use of this software.
6 |
7 | Permission is granted to anyone to use this software for any purpose,
8 | including commercial applications, and to alter it and redistribute it
9 | freely, subject to the following restrictions:
10 |
11 | 1. The origin of this software must not be misrepresented; you must not
12 | claim that you wrote the original software. If you use this software
13 | in a product, an acknowledgment in the product documentation would be
14 | appreciated but is not required.
15 | 2. Altered source versions must be plainly marked as such, and must not be
16 | misrepresented as being the original software.
17 | 3. This notice may not be removed or altered from any source distribution.
18 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Unify :link:
2 | =====
3 |
4 | **Unify** is a C++11 function to normalize resource identificators.
5 |
6 | Unify transforms any physical resource string to a unified string, called UID (Unified ID). Any absolute, relative, virtual and/or networks paths, URI, URL or ID will transform to an UID. Basically `unify(src)` does a string transformation from given string to a sorted `[a-zA-Z0-9-]+` pattern, which is guaranteed to remain inmutable (on a high degree) on code, even if physical source is altered externally.
7 |
8 | ## Features
9 | - [x] Unified folder/asset separators.
10 | - [x] Unified absolute, relative, virtual and remote paths.
11 | - [x] Unified uppercases, lowercases, whitespaces and hyphens.
12 | - [x] Unified extensions.
13 | - [x] Unified typos on double extensions and double punctuations.
14 | - [x] Unified typos on many diacritics.
15 | - [x] Unified AoS (OO) and SoA (ECS) disk layouts.
16 | - [x] Unified plurals as well (if using English words).
17 | - [x] Unified SOV, SVO, VSO, VOS, OVS, OSV subject/verb/object language topologies.
18 | - [x] Unified tagging (useful when globbing and deploying files and/or directories)
19 | - [x] Unified consistency. Reunification as a lossless process.
20 | - [x] Unify is header-only, cross-platform and standalone.
21 | - [x] Unify is ZLIB/LibPNG licensed.
22 |
23 | ## Public API
24 | ```c++
25 | // Convert anything to an UID
26 | // Additionally, if tags != null pushback all parsed tags found
27 | string unify( const string &uri, vector *tags = 0 );
28 | ```
29 |
30 | ## Quick tutorial TL;DR
31 | ```c++
32 | // unified folder/asset separators
33 | std::string test = unify("folder\\asset");
34 | assert( test == unify("folder/asset") );
35 | assert( test == unify("folder-asset") );
36 | assert( test == unify("folder|asset") );
37 | assert( test == unify("folder:asset") );
38 | assert( test == unify("folder;asset") );
39 | assert( test == unify("folder,asset") );
40 | assert( test == unify("[folder]asset") );
41 | assert( test == unify("asset(folder)") );
42 | // -> asset_folder
43 |
44 | // unified absolute, relative, virtual and remote paths
45 | test = unify("~home/game/folder/asset.jpg");
46 | assert( test == unify("~user/game1/folder/asset.jpg") );
47 | assert( test == unify("~mark/game2/folder/asset.jpg") );
48 | assert( test == unify("~john/game3/data/folder/asset.jpg") );
49 | assert( test == unify("../folder/asset.jpg") );
50 | assert( test == unify("C:\\data\\folder\\asset.jpg") );
51 | assert( test == unify("C:/game/data/folder/asset.jpg") );
52 | assert( test == unify("data.zip/data/folder/asset.jpg") );
53 | assert( test == unify("virtual.rar/folder/asset.jpg") );
54 | assert( test == unify("http://web.domain.com%20/folder/asset.jpg?blabla=123&abc=123#qwe") );
55 | // -> asset_folder
56 |
57 | // unified uppercases, lowercases, whitespaces and hyphens
58 | assert( unify("mesh/main-character") == "character_main_mesh" );
59 | assert( unify("mesh/main_character") == "character_main_mesh" );
60 | assert( unify("mesh/Main Character") == "character_main_mesh" );
61 | assert( unify("mesh / Main character ") == "character_main_mesh" );
62 | // -> character_main_mesh
63 |
64 | // unified extensions
65 | assert( unify("music/theme.ogg") == "music_theme" );
66 | assert( unify("music/theme.wav") == "music_theme" );
67 | assert( unify("ui/logo.png") == "logo_ui" );
68 | assert( unify("ui/logo.webp") == "logo_ui" );
69 | // -> music_theme, -> logo_ui
70 |
71 | // unified typos on double extensions and double punctuations
72 | assert( unify("game/logo.bmp.png") == unify("game/logo.bmp") );
73 | assert( unify("game/logo.png") == unify("game/logo..png") );
74 | // -> game_logo
75 |
76 | // unified typos on many diacritics
77 | assert( unify("âñimátïón/wàlk") == unify("animation/walk") );
78 | // -> animation_walk
79 |
80 | // unified AoS (OO) and SoA (ECS) disk layouts
81 | // unified plurals as well (if using English words)
82 | assert( unify("sounds/kid") == unify("kid/sound") );
83 | assert( unify("sprites/kid") == unify("kid/sprite") );
84 | assert( unify("sounds/car") == unify("car/sound") );
85 | assert( unify("sprites/car") == unify("car/sprite") );
86 | // -> car_sound, car_sprite, kid_sound, kid_sprite
87 |
88 | // unified SOV, SVO, VSO, VOS, OVS, OSV subject/verb/object language topologies
89 | test = unify("player-joins-scene.intro");
90 | assert( test == unify("player-scene-join.intro") );
91 | assert( test == unify("join-player-scene.intro") );
92 | assert( test == unify("join-scene-player.intro") );
93 | assert( test == unify("scene-join-player.intro") );
94 | assert( test == unify("scene-player-join.intro") );
95 | // -> join_player_scene
96 |
97 | // unified tagging (useful when globbing and deploying files and/or directories)
98 | test = unify("splash/logo");
99 | assert( unify("/splash/#win32/logo") == test );
100 | assert( unify("splash #mobile/logo #win32=always.png") == test );
101 | // -> logo_splash
102 |
103 | // unified consistency. reunification as a lossless process
104 | assert( unify( unify("roses-are-red") ) == unify("roses-are-red") );
105 | // -> are_red_rose
106 | ```
107 |
108 | ## Showcase
109 | - John is a lead coder and must finish his game at time.
110 | - When dealing with asset identifiers and filesystems, John just wants to write the identifiers once and forget about them during development (even after deployment!).
111 | - To achieve this:
112 | - John names every asset in the game with an identifier.
113 | - John embeds Unify over a thin disk wrapper.
114 | - From this point:
115 | - Everybody in the production team can `#tag` files and folders from now as much as needed (or even `#tag=with-attributes`). These tags will be automatically removed from identifers once unified and will help John later, specially when globbing files and prior to deploy a release (more on this later).
116 | - Whitespaces, underscores, uppercase characters, diacritics, double extensions (and a large list of mistakes) will be fixed automatically.
117 | - Artists will be able to change (on a high degree) the asset names and/or folders on disk at any the time without telling the coders (just because artists are always that consistent).
118 | - Programmers will be able to transcode files to different formats without telling their technical directors: like going from .etc1 (desktop) to .pvr (iOS) (just because programmers are always that efficent).
119 | - Technical directors will be able to encrypt, repack and compress the filesystem into a completely different filesystem 2 hours before the release without telling the CEO (just because directors are always that security concerned).
120 | - And CEOs just can still take that lovely bath on the beach with no interruptions.
121 | - This is actually John's wrapper:
122 |
123 | ```c++
124 | #include