Хранить данные в URIs после хеша

С объединением Вы, как только предполагается, используете один из элементов, потому что они все хранятся в том же пятне. Это делает его полезным, когда Вы хотите сохранить что-то, что могло быть одним из нескольких типов. Структура, с другой стороны, имеет отдельную ячейку памяти для каждого из ее элементов, и они все могут использоваться сразу.

Для предоставления конкретного примера их использования я работал над интерпретатором Схемы только что, и я по существу накладывал типы данных Схемы на типы данных C. Это включенное хранение в структуре перечисление, указывающее на тип значения и объединения для хранения то значение.

union foo {
  int a;   // can't use both a and b at once
  char b;
} foo;

struct bar {
  int a;   // can use both a and b simultaneously
  char b;
} bar;

union foo x;
x.a = 3; // OK
x.b = 'c'; // NO! this affects the value of x.a!

struct bar y;
y.a = 3; // OK
y.b = 'c'; // OK

редактирование: , Если Вы задаетесь вопросом, какие настройки x.b к 'c' изменяют значение x.a к, с технической точки зрения это не определено. На большинстве современных машин символ составляет 1 байт, и интервал составляет 4 байта, таким образом давание x.b значение 'c' также дает первый байт x.a то же самое значение:

union foo x;
x.a = 3;
x.b = 'c';
printf("%i, %i\n", x.a, x.b);

печать

99, 99

, Почему два значения являются тем же? Поскольку последние 3 байта интервала 3 являются всем нулем, таким образом, это также читается как 99. Если мы вставим большее число для x.a, Вы будете видеть, что это не всегда имеет место:

union foo x;
x.a = 387439;
x.b = 'c';
printf("%i, %i\n", x.a, x.b);

печать

387427, 99

Для получения более внимательного рассмотрения фактических значений памяти давайте установим и распечатаем значения в шестнадцатеричном числе:

union foo x;
x.a = 0xDEADBEEF;
x.b = 0x22;
printf("%x, %x\n", x.a, x.b);

печать

deadbe22, 22

можно ясно видеть, где 0x22 перезаписал 0xEF.

, НО

В C, порядок байтов в интервале не определен. Эта программа перезаписала 0xEF с 0x22 на моем Mac, но существуют другие платформы, где это перезаписало бы 0xDE вместо этого, потому что порядок байтов, которые составляют интервал, был инвертирован. Поэтому при записи программы, Вы никогда не должны полагаться на поведение перезаписи определенных данных в объединении, потому что это не портативно.

Для большего количества чтения на упорядочивании байтов, проверьте порядок байтов .

5
задан Josh Lee 7 September 2010 в 12:53
поделиться

2 ответа

Для всех, кто интересуется, вот решение Я придумал:

/**
 * Copyright 2009 by David Kerkeslager
 * Released under the BSD License (http://davidkerkeslager.com/license.txt).
 *
 * This library defines an object-literal which allows one to store key/value pairs after the hash (#) in the URI.
 * The syntax of the storage is modeled after the way that GET variables are stored after the question mark (?) in
 * the URI.
 *
 * Example URI: "http://www.foo.com/index.html#foo=bar&baz=quux"
 *
 * Note: it should be obvious that this should not be used for storing private data of any kind.
 */

var URIHash =
{
    /**
     * Dump the contents of the URI hash into an associative array. If the hash is invalid, the method returns
     * undefined.
     */
    dump : function()
    {
        var hash = document.location.hash;
        var dump = new Array();

        if(hash.length == 0) return dump;

        hash = hash.substring(1).split('&');

        for(var key in hash)
        {
            var pair = hash[key].split('=');

            if(pair.length != 2 || pair[0] in dump)
                return undefined;

            // escape for storage
            dump[unescape(pair[0])] = unescape(pair[1]);
        }

        return dump;
    },

    /**
     * Takes an associative array and stores it in the URI as a hash after the # prefix, replacing any pre-
     * existing hash.
     */
    load : function(array)
    {
        var first = true;
        var hash = '';

        for(var key in array)
        {
            if(!first) hash += '&';
            hash += escape(key) + '=' + escape(array[key]);
        }

        document.location.hash = hash;
    },

    /**
     * Get the value of a key from the hash.  If the hash does not contain the key or the hash is invalid,
     * the function returns undefined.
     */
    get : function(key)
    {
        return this.dump()[key];
    },

    /**
     * Set the value of a key in the hash.  If the key does not exist, the key/value pair is added.
     */
    set : function(key,value)
    {
        var dump = this.dump();
        dump[key] = value;

        var hash = new Array();

        for(var key in dump)
            hash.push(escape(key) + '=' + escape(dump[key]));

        document.location.hash = hash.join('&');
    }
}
8
ответ дан 14 December 2019 в 01:13
поделиться

Вы можете хранить данные JSON после хэша. Я старался сделать это - это позволило бы избежать синтаксического анализа, хотя вы можете стать жертвой взлома.

1
ответ дан 14 December 2019 в 01:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: