text:
#ifndef _FSL_LTC_EDMA_H_
#define _FSL_LTC_EDMA_H_

#include "fsl_common.h"

#include "fsl_ltc.h"
#include "fsl_dmamux.h"
#include "fsl_edma.h"

/*!
 * @addtogroup ltc_edma_driver
 * @{
 */

/*******************************************************************************
 * Definitions
 ******************************************************************************/

/* @brief The LTC eDMA handle type. */
typedef struct _ltc_edma_handle ltc_edma_handle_t;

/*! @brief LTC eDMA callback function. */
typedef void (*ltc_edma_callback_t)(LTC_Type *base, ltc_edma_handle_t *handle, status_t status, void *userData);

/*! @brief LTC eDMA state machine function. It is defined only for private usage inside LTC eDMA driver. */
typedef status_t (*ltc_edma_state_machine_t)(LTC_Type *base, ltc_edma_handle_t *handle);

/*!
* @brief LTC eDMA handle. It is defined only for private usage inside LTC eDMA driver.
*/
struct _ltc_edma_handle
{
    ltc_edma_callback_t callback; /*!< Callback function. */
    void *userData;               /*!< LTC callback function parameter.*/

    edma_handle_t *inputFifoEdmaHandle;  /*!< The eDMA TX channel used. */
    edma_handle_t *outputFifoEdmaHandle; /*!< The eDMA RX channel used. */

    ltc_edma_state_machine_t state_machine; /*!< State machine. */
    uint32_t state;                         /*!< Internal state. */
    const uint8_t *inData;                  /*!< Input data. */
    uint8_t *outData;                       /*!< Output data. */
    uint32_t size;                          /*!< Size of input and output data in bytes.*/
    uint32_t modeReg;                       /*!< LTC mode register.*/
    /* Used by AES CTR*/
    uint8_t *counter;   /*!< Input counter (updates on return)*/
    const uint8_t *key; /*!< Input key to use for forward AES cipher*/
    uint32_t keySize;   /*!< Size of the input key, in bytes. Must be 16, 24, or 32.*/
    uint8_t
        *counterlast; /*!< Output cipher of last counter, for chained CTR calls. NULL can be passed if chained calls are
                         not used.*/
    uint32_t *szLeft; /*!< Output number of bytes in left unused in counterlast block. NULL can be passed if chained
                         calls are not used.*/
    uint32_t lastSize; /*!< Last size.*/
};

/*******************************************************************************
 * API
 ******************************************************************************/

#if defined(__cplusplus)
extern "C" {
#endif

/*!
 * @brief Init the LTC eDMA handle which is used in transcational functions
 * @param base      LTC module base address
 * @param handle    Pointer to ltc_edma_handle_t structure
 * @param callback  Callback function, NULL means no callback.
 * @param userData  Callback function parameter.
 * @param inputFifoEdmaHandle User requested eDMA handle for Input FIFO eDMA.
 * @param outputFifoEdmaHandle User requested eDMA handle for Output FIFO eDMA.
 */
void LTC_CreateHandleEDMA(LTC_Type *base,
                          ltc_edma_handle_t *handle,
                          ltc_edma_callback_t callback,
                          void *userData,
                          edma_handle_t *inputFifoEdmaHandle,
                          edma_handle_t *outputFifoEdmaHandle);

/*! @}*/

/*******************************************************************************
 * AES API
 ******************************************************************************/

/*!
 * @addtogroup ltc_edma_driver_aes
 * @{
 */

/*!
 * @brief Encrypts AES using the ECB block mode.
 *
 * Encrypts AES using the ECB block mode.
 *
 * @param base LTC peripheral base address
 * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state.
 * @param plaintext Input plain text to encrypt
 * @param[out] ciphertext Output cipher text
 * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
 * @param key Input key to use for encryption
 * @param keySize Size of the input key, in bytes. Must be 16, 24, or 32.
 * @return Status from encrypt operation
 */
status_t LTC_AES_EncryptEcbEDMA(LTC_Type *base,
                                ltc_edma_handle_t *handle,
                                const uint8_t *plaintext,
                                uint8_t *ciphertext,
                                uint32_t size,
                                const uint8_t *key,
                                uint32_t keySize);

/*!
 * @brief Decrypts AES using ECB block mode.
 *
 * Decrypts AES using ECB block mode.
 *
 * @param base LTC peripheral base address
 * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state.
 * @param ciphertext Input cipher text to decrypt
 * @param[out] plaintext Output plain text
 * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
 * @param key Input key.
 * @param keySize Size of the input key, in bytes. Must be 16, 24, or 32.
 * @param keyType Input type of the key (allows to directly load decrypt key for AES ECB decrypt operation.)
 * @return Status from decrypt operation
 */
status_t LTC_AES_DecryptEcbEDMA(LTC_Type *base,
                                ltc_edma_handle_t *handle,
                                const uint8_t *ciphertext,
                                uint8_t *plaintext,
                                uint32_t size,
                                const uint8_t *key,
                                uint32_t keySize,
                                ltc_aes_key_t keyType);

/*!
 * @brief Encrypts AES using CBC block mode.
 *
 * @param base LTC peripheral base address
 * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state.
 * @param plaintext Input plain text to encrypt
 * @param[out] ciphertext Output cipher text
 * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
 * @param iv Input initial vector to combine with the first input block.
 * @param key Input key to use for encryption
 * @param keySize Size of the input key, in bytes. Must be 16, 24, or 32.
 * @return Status from encrypt operation
 */
status_t LTC_AES_EncryptCbcEDMA(LTC_Type *base,
                                ltc_edma_handle_t *handle,
                                const uint8_t *plaintext,
                                uint8_t *ciphertext,
                                uint32_t size,
                                const uint8_t iv[LTC_AES_IV_SIZE],
                                const uint8_t *key,
                                uint32_t keySize);

/*!
 * @brief Decrypts AES using CBC block mode.
 *
 * @param base LTC peripheral base address
 * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state.
 * @param ciphertext Input cipher text to decrypt
 * @param[out] plaintext Output plain text
 * @param size Size of input and output data in bytes. Must be multiple of 16 bytes.
 * @param iv Input initial vector to combine with the first input block.
 * @param key Input key to use for decryption
 * @param keySize Size of the input key, in bytes. Must be 16, 24, or 32.
 * @param keyType Input type of the key (allows to directly load decrypt key for AES CBC decrypt operation.)
 * @return Status from decrypt operation
 */
status_t LTC_AES_DecryptCbcEDMA(LTC_Type *base,
                                ltc_edma_handle_t *handle,
                                const uint8_t *ciphertext,
                                uint8_t *plaintext,
                                uint32_t size,
                                const uint8_t iv[LTC_AES_IV_SIZE],
                                const uint8_t *key,
                                uint32_t keySize,
                                ltc_aes_key_t keyType);

/*!
 * @brief Encrypts or decrypts AES using CTR block mode.
 *
 * Encrypts or decrypts AES using CTR block mode.
 * AES CTR mode uses only forward AES cipher and same algorithm for encryption and decryption.
 * The only difference between encryption and decryption is that, for encryption, the input argument
 * is plain text and the output argument is cipher text. For decryption, the input argument is cipher text
 * and the output argument is plain text.
 *
 * @param base LTC peripheral base address
 * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state.
 * @param input Input data for CTR block mode
 * @param[out] output Output data for CTR block mode
 * @param size Size of input and output data in bytes
 * @param[in,out] counter Input counter (updates on return)
 * @param key Input key to use for forward AES cipher
 * @param keySize Size of the input key, in bytes. Must be 16, 24, or 32.
 * @param[out] counterlast Output cipher of last counter, for chained CTR calls. NULL can be passed if chained calls are
 * not used.
 * @param[out] szLeft Output number of bytes in left unused in counterlast block. NULL can be passed if chained calls
 * are not used.
 * @return Status from encrypt operation
 */
status_t LTC_AES_CryptCtrEDMA(LTC_Type *base,
                              ltc_edma_handle_t *handle,
                              const uint8_t *input,
                              uint8_t *output,
                              uint32_t size,
                              uint8_t counter[LTC_AES_BLOCK_SIZE],
                              const uint8_t *key,
                              uint32_t keySize,
                              uint8_t counterlast[LTC_AES_BLOCK_SIZE],
                              uint32_t *szLeft);

/*! AES CTR decrypt is mapped to the AES CTR generic operation */
#define LTC_AES_DecryptCtrEDMA(base, handle, input, output, size, counter, key, keySize, counterlast, szLeft) \
    LTC_AES_CryptCtrEDMA(base, handle, input, output, size, counter, key, keySize, counterlast, szLeft)

/*! AES CTR encrypt is mapped to the AES CTR generic operation */
#define LTC_AES_EncryptCtrEDMA(base, handle, input, output, size, counter, key, keySize, counterlast, szLeft) \
    LTC_AES_CryptCtrEDMA(base, handle, input, output, size, counter, key, keySize, counterlast, szLeft)

/*!
 *@}
 */

/*******************************************************************************
 * DES API
 ******************************************************************************/
/*!
 * @addtogroup ltc_edma_driver_des
 * @{
 */
/*!
 * @brief Encrypts DES using ECB block mode.
 *
 * Encrypts DES using ECB block mode.
 *
 * @param base LTC peripheral base address
 * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state.
 * @param plaintext Input plaintext to encrypt
 * @param[out] ciphertext Output ciphertext
 * @param size Size of input and output data in bytes. Must be multiple of 8 bytes.
 * @param key Input key to use for encryption
 * @return Status from encrypt/decrypt operation
 */
status_t LTC_DES_EncryptEcbEDMA(LTC_Type *base,
                                ltc_edma_handle_t *handle,
                                const uint8_t *plaintext,
                                uint8_t *ciphertext,
                                uint32_t size,
                                const uint8_t key[LTC_DES_KEY_SIZE]);

/*!
 * @brief Decrypts DES using ECB block mode.
 *
 * Decrypts DES using ECB block mode.
 *
 * @param base LTC peripheral base address
 * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state.
 * @param ciphertext Input ciphertext to decrypt
 * @param[out] plaintext Output plaintext
 * @param size Size of input and output data in bytes. Must be multiple of 8 bytes.
 * @param key Input key to use for decryption
 * @return Status from encrypt/decrypt operation
 */
status_t LTC_DES_DecryptEcbEDMA(LTC_Type *base,
                                ltc_edma_handle_t *handle,
                                const uint8_t *ciphertext,
                                uint8_t *plaintext,
                                uint32_t size,
                                const uint8_t key[LTC_DES_KEY_SIZE]);

/*!
 * @brief Encrypts DES using CBC block mode.
 *
 * Encrypts DES using CBC block mode.
 *
 * @param base LTC peripheral base address
 * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state.
 * @param plaintext Input plaintext to encrypt
 * @param[out] ciphertext Ouput ciphertext
 * @param size Size of input and output data in bytes
 * @param iv Input initial vector to combine with the first plaintext block.
 *           The iv does not need to be secret, but it must be unpredictable.
 * @param key Input key to use for encryption
 * @return Status from encrypt/decrypt operation
 */
status_t LTC_DES_EncryptCbcEDMA(LTC_Type *base,
                                ltc_edma_handle_t *handle,
                                const uint8_t *plaintext,
                                uint8_t *ciphertext,
                                uint32_t size,
                                const uint8_t iv[LTC_DES_IV_SIZE],
                                const uint8_t key[LTC_DES_KEY_SIZE]);

/*!
 * @brief Decrypts DES using CBC block mode.
 *
 * Decrypts DES using CBC block mode.
 *
 * @param base LTC peripheral base address
 * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state.
 * @param ciphertext Input ciphertext to decrypt
 * @param[out] plaintext Output plaintext
 * @param size Size of input data in bytes
 * @param iv Input initial vector to combine with the first plaintext block.
 *           The iv does not need to be secret, but it must be unpredictable.
 * @param key Input key to use for decryption
 * @return Status from encrypt/decrypt operation
 */
status_t LTC_DES_DecryptCbcEDMA(LTC_Type *base,
                                ltc_edma_handle_t *handle,
                                const uint8_t *ciphertext,
                                uint8_t *plaintext,
                                uint32_t size,
                                const uint8_t iv[LTC_DES_IV_SIZE],
                                const uint8_t key[LTC_DES_KEY_SIZE]);

/*!
 * @brief Encrypts DES using CFB block mode.
 *
 * Encrypts DES using CFB block mode.
 *
 * @param base LTC peripheral base address
 * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state.
 * @param plaintext Input plaintext to encrypt
 * @param size Size of input data in bytes
 * @param iv Input initial block.
 * @param key Input key to use for encryption
 * @param[out] ciphertext Output ciphertext
 * @return Status from encrypt/decrypt operation
 */
status_t LTC_DES_EncryptCfbEDMA(LTC_Type *base,
                                ltc_edma_handle_t *handle,
                                const uint8_t *plaintext,
                                uint8_t *ciphertext,
                                uint32_t size,
                                const uint8_t iv[LTC_DES_IV_SIZE],
                                const uint8_t key[LTC_DES_KEY_SIZE]);

/*!
 * @brief Decrypts DES using CFB block mode.
 *
 * Decrypts DES using CFB block mode.
 *
 * @param base LTC peripheral base address
 * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state.
 * @param ciphertext Input ciphertext to decrypt
 * @param[out] plaintext Output plaintext
 * @param size Size of input and output data in bytes
 * @param iv Input initial block.
 * @param key Input key to use for decryption
 * @return Status from encrypt/decrypt operation
 */
status_t LTC_DES_DecryptCfbEDMA(LTC_Type *base,
                                ltc_edma_handle_t *handle,
                                const uint8_t *ciphertext,
                                uint8_t *plaintext,
                                uint32_t size,
                                const uint8_t iv[LTC_DES_IV_SIZE],
                                const uint8_t key[LTC_DES_KEY_SIZE]);

/*!
 * @brief Encrypts DES using OFB block mode.
 *
 * Encrypts DES using OFB block mode.
 *
 * @param base LTC peripheral base address
 * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state.
 * @param plaintext Input plaintext to encrypt
 * @param[out] ciphertext Output ciphertext
 * @param size Size of input and output data in bytes
 * @param iv Input unique input vector. The OFB mode requires that the IV be unique
 *           for each execution of the mode under the given key.
 * @param key Input key to use for encryption
 * @return Status from encrypt/decrypt operation
 */
status_t LTC_DES_EncryptOfbEDMA(LTC_Type *base,
                                ltc_edma_handle_t *handle,
                                const uint8_t *plaintext,
                                uint8_t *ciphertext,
                                uint32_t size,
                                const uint8_t iv[LTC_DES_IV_SIZE],
                                const uint8_t key[LTC_DES_KEY_SIZE]);

/*!
 * @brief Decrypts DES using OFB block mode.
 *
 * Decrypts DES using OFB block mode.
 *
 * @param base LTC peripheral base address
 * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state.
 * @param ciphertext Input ciphertext to decrypt
 * @param[out] plaintext Output plaintext
 * @param size Size of input and output data in bytes. Must be multiple of 8 bytes.
 * @param iv Input unique input vector. The OFB mode requires that the IV be unique
 *           for each execution of the mode under the given key.
 * @param key Input key to use for decryption
 * @return Status from encrypt/decrypt operation
 */
status_t LTC_DES_DecryptOfbEDMA(LTC_Type *base,
                                ltc_edma_handle_t *handle,
                                const uint8_t *ciphertext,
                                uint8_t *plaintext,
                                uint32_t size,
                                const uint8_t iv[LTC_DES_IV_SIZE],
                                const uint8_t key[LTC_DES_KEY_SIZE]);

/*!
 * @brief Encrypts triple DES using ECB block mode with two keys.
 *
 * Encrypts triple DES using ECB block mode with two keys.
 *
 * @param base LTC peripheral base address
 * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state.
 * @param plaintext Input plaintext to encrypt
 * @param[out] ciphertext Output ciphertext
 * @param size Size of input and output data in bytes. Must be multiple of 8 bytes.
 * @param key1 First input key for key bundle
 * @param key2 Second input key for key bundle
 * @return Status from encrypt/decrypt operation
 */
status_t LTC_DES2_EncryptEcbEDMA(LTC_Type *base,
                                 ltc_edma_handle_t *handle,
                                 const uint8_t *plaintext,
                                 uint8_t *ciphertext,
                                 uint32_t size,
                                 const uint8_t key1[LTC_DES_KEY_SIZE],
                                 const uint8_t key2[LTC_DES_KEY_SIZE]);

/*!
 * @brief Decrypts triple DES using ECB block mode with two keys.
 *
 * Decrypts triple DES using ECB block mode with two keys.
 *
 * @param base LTC peripheral base address
 * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state.
 * @param ciphertext Input ciphertext to decrypt
 * @param[out] plaintext Output plaintext
 * @param size Size of input and output data in bytes. Must be multiple of 8 bytes.
 * @param key1 First input key for key bundle
 * @param key2 Second input key for key bundle
 * @return Status from encrypt/decrypt operation
 */
status_t LTC_DES2_DecryptEcbEDMA(LTC_Type *base,
                                 ltc_edma_handle_t *handle,
                                 const uint8_t *ciphertext,
                                 uint8_t *plaintext,
                                 uint32_t size,
                                 const uint8_t key1[LTC_DES_KEY_SIZE],
                                 const uint8_t key2[LTC_DES_KEY_SIZE]);

/*!
 * @brief Encrypts triple DES using CBC block mode with two keys.
 *
 * Encrypts triple DES using CBC block mode with two keys.
 *
 * @param base LTC peripheral base address
 * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state.
 * @param plaintext Input plaintext to encrypt
 * @param[out] ciphertext Output ciphertext
 * @param size Size of input and output data in bytes
 * @param iv Input initial vector to combine with the first plaintext block.
 *           The iv does not need to be secret, but it must be unpredictable.
 * @param key1 First input key for key bundle
 * @param key2 Second input key for key bundle
 * @return Status from encrypt/decrypt operation
 */
status_t LTC_DES2_EncryptCbcEDMA(LTC_Type *base,
                                 ltc_edma_handle_t *handle,
                                 const uint8_t *plaintext,
                                 uint8_t *ciphertext,
                                 uint32_t size,
                                 const uint8_t iv[LTC_DES_IV_SIZE],
                                 const uint8_t key1[LTC_DES_KEY_SIZE],
                                 const uint8_t key2[LTC_DES_KEY_SIZE]);

/*!
 * @brief Decrypts triple DES using CBC block mode with two keys.
 *
 * Decrypts triple DES using CBC block mode with two keys.
 *
 * @param base LTC peripheral base address
 * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state.
 * @param ciphertext Input ciphertext to decrypt
 * @param[out] plaintext Output plaintext
 * @param size Size of input and output data in bytes
 * @param iv Input initial vector to combine with the first plaintext block.
 *           The iv does not need to be secret, but it must be unpredictable.
 * @param key1 First input key for key bundle
 * @param key2 Second input key for key bundle
 * @return Status from encrypt/decrypt operation
 */
status_t LTC_DES2_DecryptCbcEDMA(LTC_Type *base,
                                 ltc_edma_handle_t *handle,
                                 const uint8_t *ciphertext,
                                 uint8_t *plaintext,
                                 uint32_t size,
                                 const uint8_t iv[LTC_DES_IV_SIZE],
                                 const uint8_t key1[LTC_DES_KEY_SIZE],
                                 const uint8_t key2[LTC_DES_KEY_SIZE]);

/*!
 * @brief Encrypts triple DES using CFB block mode with two keys.
 *
 * Encrypts triple DES using CFB block mode with two keys.
 *
 * @param base LTC peripheral base address
 * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state.
 * @param plaintext Input plaintext to encrypt
 * @param[out] ciphertext Output ciphertext
 * @param size Size of input and output data in bytes
 * @param iv Input initial block.
 * @param key1 First input key for key bundle
 * @param key2 Second input key for key bundle
 * @return Status from encrypt/decrypt operation
 */
status_t LTC_DES2_EncryptCfbEDMA(LTC_Type *base,
                                 ltc_edma_handle_t *handle,
                                 const uint8_t *plaintext,
                                 uint8_t *ciphertext,
                                 uint32_t size,
                                 const uint8_t iv[LTC_DES_IV_SIZE],
                                 const uint8_t key1[LTC_DES_KEY_SIZE],
                                 const uint8_t key2[LTC_DES_KEY_SIZE]);

/*!
 * @brief Decrypts triple DES using CFB block mode with two keys.
 *
 * Decrypts triple DES using CFB block mode with two keys.
 *
 * @param base LTC peripheral base address
 * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state.
 * @param ciphertext Input ciphertext to decrypt
 * @param[out] plaintext Output plaintext
 * @param size Size of input and output data in bytes
 * @param iv Input initial block.
 * @param key1 First input key for key bundle
 * @param key2 Second input key for key bundle
 * @return Status from encrypt/decrypt operation
 */
status_t LTC_DES2_DecryptCfbEDMA(LTC_Type *base,
                                 ltc_edma_handle_t *handle,
                                 const uint8_t *ciphertext,
                                 uint8_t *plaintext,
                                 uint32_t size,
                                 const uint8_t iv[LTC_DES_IV_SIZE],
                                 const uint8_t key1[LTC_DES_KEY_SIZE],
                                 const uint8_t key2[LTC_DES_KEY_SIZE]);

/*!
 * @brief Encrypts triple DES using OFB block mode with two keys.
 *
 * Encrypts triple DES using OFB block mode with two keys.
 *
 * @param base LTC peripheral base address
 * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state.
 * @param plaintext Input plaintext to encrypt
 * @param[out] ciphertext Output ciphertext
 * @param size Size of input and output data in bytes
 * @param iv Input unique input vector. The OFB mode requires that the IV be unique
 *           for each execution of the mode under the given key.
 * @param key1 First input key for key bundle
 * @param key2 Second input key for key bundle
 * @return Status from encrypt/decrypt operation
 */
status_t LTC_DES2_EncryptOfbEDMA(LTC_Type *base,
                                 ltc_edma_handle_t *handle,
                                 const uint8_t *plaintext,
                                 uint8_t *ciphertext,
                                 uint32_t size,
                                 const uint8_t iv[LTC_DES_IV_SIZE],
                                 const uint8_t key1[LTC_DES_KEY_SIZE],
                                 const uint8_t key2[LTC_DES_KEY_SIZE]);

/*!
 * @brief Decrypts triple DES using OFB block mode with two keys.
 *
 * Decrypts triple DES using OFB block mode with two keys.
 *
 * @param base LTC peripheral base address
 * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state.
 * @param ciphertext Input ciphertext to decrypt
 * @param[out] plaintext Output plaintext
 * @param size Size of input and output data in bytes
 * @param iv Input unique input vector. The OFB mode requires that the IV be unique
 *           for each execution of the mode under the given key.
 * @param key1 First input key for key bundle
 * @param key2 Second input key for key bundle
 * @return Status from encrypt/decrypt operation
 */
status_t LTC_DES2_DecryptOfbEDMA(LTC_Type *base,
                                 ltc_edma_handle_t *handle,
                                 const uint8_t *ciphertext,
                                 uint8_t *plaintext,
                                 uint32_t size,
                                 const uint8_t iv[LTC_DES_IV_SIZE],
                                 const uint8_t key1[LTC_DES_KEY_SIZE],
                                 const uint8_t key2[LTC_DES_KEY_SIZE]);

/*!
 * @brief Encrypts triple DES using ECB block mode with three keys.
 *
 * Encrypts triple DES using ECB block mode with three keys.
 *
 * @param base LTC peripheral base address
 * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state.
 * @param plaintext Input plaintext to encrypt
 * @param[out] ciphertext Output ciphertext
 * @param size Size of input and output data in bytes. Must be multiple of 8 bytes.
 * @param key1 First input key for key bundle
 * @param key2 Second input key for key bundle
 * @param key3 Third input key for key bundle
 * @return Status from encrypt/decrypt operation
 */
status_t LTC_DES3_EncryptEcbEDMA(LTC_Type *base,
                                 ltc_edma_handle_t *handle,
                                 const uint8_t *plaintext,
                                 uint8_t *ciphertext,
                                 uint32_t size,
                                 const uint8_t key1[LTC_DES_KEY_SIZE],
                                 const uint8_t key2[LTC_DES_KEY_SIZE],
                                 const uint8_t key3[LTC_DES_KEY_SIZE]);

/*!
 * @brief Decrypts triple DES using ECB block mode with three keys.
 *
 * Decrypts triple DES using ECB block mode with three keys.
 *
 * @param base LTC peripheral base address
 * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state.
 * @param ciphertext Input ciphertext to decrypt
 * @param[out] plaintext Output plaintext
 * @param size Size of input and output data in bytes. Must be multiple of 8 bytes.
 * @param key1 First input key for key bundle
 * @param key2 Second input key for key bundle
 * @param key3 Third input key for key bundle
 * @return Status from encrypt/decrypt operation
 */
status_t LTC_DES3_DecryptEcbEDMA(LTC_Type *base,
                                 ltc_edma_handle_t *handle,
                                 const uint8_t *ciphertext,
                                 uint8_t *plaintext,
                                 uint32_t size,
                                 const uint8_t key1[LTC_DES_KEY_SIZE],
                                 const uint8_t key2[LTC_DES_KEY_SIZE],
                                 const uint8_t key3[LTC_DES_KEY_SIZE]);

/*!
 * @brief Encrypts triple DES using CBC block mode with three keys.
 *
 * Encrypts triple DES using CBC block mode with three keys.
 *
 * @param base LTC peripheral base address
 * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state.
 * @param plaintext Input plaintext to encrypt
 * @param[out] ciphertext Output ciphertext
 * @param size Size of input data in bytes
 * @param iv Input initial vector to combine with the first plaintext block.
 *           The iv does not need to be secret, but it must be unpredictable.
 * @param key1 First input key for key bundle
 * @param key2 Second input key for key bundle
 * @param key3 Third input key for key bundle
 * @return Status from encrypt/decrypt operation
 */
status_t LTC_DES3_EncryptCbcEDMA(LTC_Type *base,
                                 ltc_edma_handle_t *handle,
                                 const uint8_t *plaintext,
                                 uint8_t *ciphertext,
                                 uint32_t size,
                                 const uint8_t iv[LTC_DES_IV_SIZE],
                                 const uint8_t key1[LTC_DES_KEY_SIZE],
                                 const uint8_t key2[LTC_DES_KEY_SIZE],
                                 const uint8_t key3[LTC_DES_KEY_SIZE]);

/*!
 * @brief Decrypts triple DES using CBC block mode with three keys.
 *
 * Decrypts triple DES using CBC block mode with three keys.
 *
 * @param base LTC peripheral base address
 * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state.
 * @param ciphertext Input ciphertext to decrypt
 * @param[out] plaintext Output plaintext
 * @param size Size of input and output data in bytes
 * @param iv Input initial vector to combine with the first plaintext block.
 *           The iv does not need to be secret, but it must be unpredictable.
 * @param key1 First input key for key bundle
 * @param key2 Second input key for key bundle
 * @param key3 Third input key for key bundle
 * @return Status from encrypt/decrypt operation
 */
status_t LTC_DES3_DecryptCbcEDMA(LTC_Type *base,
                                 ltc_edma_handle_t *handle,
                                 const uint8_t *ciphertext,
                                 uint8_t *plaintext,
                                 uint32_t size,
                                 const uint8_t iv[LTC_DES_IV_SIZE],
                                 const uint8_t key1[LTC_DES_KEY_SIZE],
                                 const uint8_t key2[LTC_DES_KEY_SIZE],
                                 const uint8_t key3[LTC_DES_KEY_SIZE]);

/*!
 * @brief Encrypts triple DES using CFB block mode with three keys.
 *
 * Encrypts triple DES using CFB block mode with three keys.
 *
 * @param base LTC peripheral base address
 * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state.
 * @param plaintext Input plaintext to encrypt
 * @param[out] ciphertext Output ciphertext
 * @param size Size of input and ouput data in bytes
 * @param iv Input initial block.
 * @param key1 First input key for key bundle
 * @param key2 Second input key for key bundle
 * @param key3 Third input key for key bundle
 * @return Status from encrypt/decrypt operation
 */
status_t LTC_DES3_EncryptCfbEDMA(LTC_Type *base,
                                 ltc_edma_handle_t *handle,
                                 const uint8_t *plaintext,
                                 uint8_t *ciphertext,
                                 uint32_t size,
                                 const uint8_t iv[LTC_DES_IV_SIZE],
                                 const uint8_t key1[LTC_DES_KEY_SIZE],
                                 const uint8_t key2[LTC_DES_KEY_SIZE],
                                 const uint8_t key3[LTC_DES_KEY_SIZE]);

/*!
 * @brief Decrypts triple DES using CFB block mode with three keys.
 *
 * Decrypts triple DES using CFB block mode with three keys.
 *
 * @param base LTC peripheral base address
 * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state.
 * @param ciphertext Input ciphertext to decrypt
 * @param[out] plaintext Output plaintext
 * @param size Size of input data in bytes
 * @param iv Input initial block.
 * @param key1 First input key for key bundle
 * @param key2 Second input key for key bundle
 * @param key3 Third input key for key bundle
 * @return Status from encrypt/decrypt operation
 */
status_t LTC_DES3_DecryptCfbEDMA(LTC_Type *base,
                                 ltc_edma_handle_t *handle,
                                 const uint8_t *ciphertext,
                                 uint8_t *plaintext,
                                 uint32_t size,
                                 const uint8_t iv[LTC_DES_IV_SIZE],
                                 const uint8_t key1[LTC_DES_KEY_SIZE],
                                 const uint8_t key2[LTC_DES_KEY_SIZE],
                                 const uint8_t key3[LTC_DES_KEY_SIZE]);

/*!
 * @brief Encrypts triple DES using OFB block mode with three keys.
 *
 * Encrypts triple DES using OFB block mode with three keys.
 *
 * @param base LTC peripheral base address
 * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state.
 * @param plaintext Input plaintext to encrypt
 * @param[out] ciphertext Output ciphertext
 * @param size Size of input and output data in bytes
 * @param iv Input unique input vector. The OFB mode requires that the IV be unique
 *           for each execution of the mode under the given key.
 * @param key1 First input key for key bundle
 * @param key2 Second input key for key bundle
 * @param key3 Third input key for key bundle
 * @return Status from encrypt/decrypt operation
 */
status_t LTC_DES3_EncryptOfbEDMA(LTC_Type *base,
                                 ltc_edma_handle_t *handle,
                                 const uint8_t *plaintext,
                                 uint8_t *ciphertext,
                                 uint32_t size,
                                 const uint8_t iv[LTC_DES_IV_SIZE],
                                 const uint8_t key1[LTC_DES_KEY_SIZE],
                                 const uint8_t key2[LTC_DES_KEY_SIZE],
                                 const uint8_t key3[LTC_DES_KEY_SIZE]);

/*!
 * @brief Decrypts triple DES using OFB block mode with three keys.
 *
 * Decrypts triple DES using OFB block mode with three keys.
 *
 * @param base LTC peripheral base address
 * @param handle pointer to ltc_edma_handle_t structure which stores the transaction state.
 * @param ciphertext Input ciphertext to decrypt
 * @param[out] plaintext Output plaintext
 * @param size Size of input and output data in bytes
 * @param iv Input unique input vector. The OFB mode requires that the IV be unique
 *           for each execution of the mode under the given key.
 * @param key1 First input key for key bundle
 * @param key2 Second input key for key bundle
 * @param key3 Third input key for key bundle
 * @return Status from encrypt/decrypt operation
 */
status_t LTC_DES3_DecryptOfbEDMA(LTC_Type *base,
                                 ltc_edma_handle_t *handle,
                                 const uint8_t *ciphertext,
                                 uint8_t *plaintext,
                                 uint32_t size,
                                 const uint8_t iv[LTC_DES_IV_SIZE],
                                 const uint8_t key1[LTC_DES_KEY_SIZE],
                                 const uint8_t key2[LTC_DES_KEY_SIZE],
                                 const uint8_t key3[LTC_DES_KEY_SIZE]);

/*!
 *@}
 */

#if defined(__cplusplus)
}
#endif

#endif /* _FSL_LTC_EDMA_H_ */


text:
require 'logger'
require File.dirname(__FILE__) + '/../test_helper'

class TestLogger < Test::Unit::TestCase

  def setup
    set_file_paths
  end

  def test_logger
    log = Tempfile.new('logfile')
    log.close

    logger = Logger.new(log.path)
    logger.level = Logger::DEBUG

    @git = Git.open(@wdir, :log => logger)
    @git.branches.size

    logc = File.read(log.path)
    assert(/INFO -- : git branch '-a'/.match(logc))
    assert(/DEBUG -- : \* git_grep/.match(logc))

    log = Tempfile.new('logfile')
    log.close
    logger = Logger.new(log.path)
    logger.level = Logger::INFO

    @git = Git.open(@wdir, :log => logger)
    @git.branches.size

    logc = File.read(log.path)
    assert(/INFO -- : git branch '-a'/.match(logc))
    assert(!/DEBUG -- : \* git_grep/.match(logc))
  end

end

redpajama_set_name: RedPajamaGithub


text:
package controllers

import play.api.mvc._

import views._

import play.api.Play
import play.api.libs.Files
import play.api.Logger.logger

object Application extends Controller {
  val SteamApiKey = loadApiKey()

  def index = Action {
    implicit request =>
      val isLoggedIn = session.get(Security.username).isDefined
      logger.info(session.get(Security.username).toString)
      val warning = flash.get("warning")
      val error = flash.get("error")
      val success = flash.get("success")
      Ok(html.index(isLoggedIn, warningMessage = warning, successMessage = success, errorMessage = error))
  }

  private def loadApiKey(): String = {
    import play.api.Play.current
    val fp = Play.getFile("conf/apiKey.txt")
    Files.readFile(fp)
  }
}


text:
/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.facebook.presto.iceberg;

import com.facebook.airlift.log.Logger;
import com.facebook.presto.hive.HdfsContext;
import com.facebook.presto.hive.HdfsEnvironment;
import com.facebook.presto.hive.HiveType;
import com.facebook.presto.hive.metastore.Column;
import com.facebook.presto.hive.metastore.ExtendedHiveMetastore;
import com.facebook.presto.hive.metastore.HivePrivilegeInfo;
import com.facebook.presto.hive.metastore.MetastoreContext;
import com.facebook.presto.hive.metastore.PrestoTableType;
import com.facebook.presto.hive.metastore.PrincipalPrivileges;
import com.facebook.presto.hive.metastore.StorageFormat;
import com.facebook.presto.hive.metastore.Table;
import com.facebook.presto.spi.PrestoException;
import com.facebook.presto.spi.SchemaTableName;
import com.facebook.presto.spi.TableNotFoundException;
import com.facebook.presto.spi.security.PrestoPrincipal;
import com.google.common.collect.ImmutableMultimap;
import org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe;
import org.apache.hadoop.mapred.FileInputFormat;
import org.apache.hadoop.mapred.FileOutputFormat;
import org.apache.iceberg.LocationProviders;
import org.apache.iceberg.TableMetadata;
import org.apache.iceberg.TableMetadataParser;
import org.apache.iceberg.TableOperations;
import org.apache.iceberg.exceptions.CommitFailedException;
import org.apache.iceberg.hive.HiveSchemaUtil;
import org.apache.iceberg.io.FileIO;
import org.apache.iceberg.io.LocationProvider;
import org.apache.iceberg.io.OutputFile;
import org.apache.iceberg.types.Types.NestedField;
import org.apache.iceberg.util.Tasks;

import javax.annotation.Nullable;
import javax.annotation.concurrent.NotThreadSafe;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;

import static com.facebook.presto.hive.HiveMetadata.TABLE_COMMENT;
import static com.facebook.presto.hive.metastore.HivePrivilegeInfo.HivePrivilege.DELETE;
import static com.facebook.presto.hive.metastore.HivePrivilegeInfo.HivePrivilege.INSERT;
import static com.facebook.presto.hive.metastore.HivePrivilegeInfo.HivePrivilege.SELECT;
import static com.facebook.presto.hive.metastore.HivePrivilegeInfo.HivePrivilege.UPDATE;
import static com.facebook.presto.iceberg.IcebergErrorCode.ICEBERG_INVALID_METADATA;
import static com.facebook.presto.iceberg.IcebergUtil.isIcebergTable;
import static com.facebook.presto.spi.security.PrincipalType.USER;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static java.lang.Integer.parseInt;
import static java.lang.String.format;
import static java.util.Objects.requireNonNull;
import static java.util.UUID.randomUUID;
import static org.apache.iceberg.BaseMetastoreTableOperations.ICEBERG_TABLE_TYPE_VALUE;
import static org.apache.iceberg.BaseMetastoreTableOperations.TABLE_TYPE_PROP;
import static org.apache.iceberg.TableMetadataParser.getFileExtension;
import static org.apache.iceberg.TableProperties.METADATA_COMPRESSION;
import static org.apache.iceberg.TableProperties.METADATA_COMPRESSION_DEFAULT;
import static org.apache.iceberg.TableProperties.WRITE_METADATA_LOCATION;

@NotThreadSafe
public class HiveTableOperations
        implements TableOperations
{
    private static final Logger log = Logger.get(HiveTableOperations.class);

    public static final String METADATA_LOCATION = "metadata_location";
    public static final String PREVIOUS_METADATA_LOCATION = "previous_metadata_location";
    private static final String METADATA_FOLDER_NAME = "metadata";

    private static final StorageFormat STORAGE_FORMAT = StorageFormat.create(
            LazySimpleSerDe.class.getName(),
            FileInputFormat.class.getName(),
            FileOutputFormat.class.getName());

    private final ExtendedHiveMetastore metastore;
    private final MetastoreContext metastoreContext;
    private final String database;
    private final String tableName;
    private final Optional<String> owner;
    private final Optional<String> location;
    private final FileIO fileIO;

    private TableMetadata currentMetadata;
    private String currentMetadataLocation;
    private boolean shouldRefresh = true;
    private int version = -1;

    public HiveTableOperations(
            ExtendedHiveMetastore metastore,
            MetastoreContext metastoreContext,
            HdfsEnvironment hdfsEnvironment,
            HdfsContext hdfsContext,
            String database,
            String table)
    {
        this(new HdfsFileIO(hdfsEnvironment, hdfsContext),
                metastore,
                metastoreContext,
                database,
                table,
                Optional.empty(),
                Optional.empty());
    }

    public HiveTableOperations(
            ExtendedHiveMetastore metastore,
            MetastoreContext metastoreContext,
            HdfsEnvironment hdfsEnvironment,
            HdfsContext hdfsContext,
            String database,
            String table,
            String owner,
            String location)
    {
        this(new HdfsFileIO(hdfsEnvironment, hdfsContext),
                metastore,
                metastoreContext,
                database,
                table,
                Optional.of(requireNonNull(owner, "owner is null")),
                Optional.of(requireNonNull(location, "location is null")));
    }

    private HiveTableOperations(
            FileIO fileIO,
            ExtendedHiveMetastore metastore,
            MetastoreContext metastoreContext,
            String database,
            String table,
            Optional<String> owner,
            Optional<String> location)
    {
        this.fileIO = requireNonNull(fileIO, "fileIO is null");
        this.metastore = requireNonNull(metastore, "metastore is null");
        this.metastoreContext = requireNonNull(metastoreContext, "metastore context is null");
        this.database = requireNonNull(database, "database is null");
        this.tableName = requireNonNull(table, "table is null");
        this.owner = requireNonNull(owner, "owner is null");
        this.location = requireNonNull(location, "location is null");
    }

    @Override
    public TableMetadata current()
    {
        if (shouldRefresh) {
            return refresh();
        }
        return currentMetadata;
    }

    @Override
    public TableMetadata refresh()
    {
        if (location.isPresent()) {
            refreshFromMetadataLocation(null);
            return currentMetadata;
        }

        Table table = getTable();

        if (!isIcebergTable(table)) {
            throw new UnknownTableTypeException(getSchemaTableName());
        }

        String metadataLocation = table.getParameters().get(METADATA_LOCATION);
        if (metadataLocation == null) {
            throw new PrestoException(ICEBERG_INVALID_METADATA, format("Table is missing [%s] property: %s", METADATA_LOCATION, getSchemaTableName()));
        }

        refreshFromMetadataLocation(metadataLocation);

        return currentMetadata;
    }

    @Override
    public void commit(@Nullable TableMetadata base, TableMetadata metadata)
    {
        requireNonNull(metadata, "metadata is null");

        // if the metadata is already out of date, reject it
        if (!Objects.equals(base, current())) {
            throw new CommitFailedException("Cannot commit: stale table metadata for %s", getSchemaTableName());
        }

        // if the metadata is not changed, return early
        if (Objects.equals(base, metadata)) {
            return;
        }

        String newMetadataLocation = writeNewMetadata(metadata, version + 1);

        // TODO: use metastore locking

        Table table;
        try {
            if (base == null) {
                String tableComment = metadata.properties().get(TABLE_COMMENT);
                Map<String, String> parameters = new HashMap<>();
                parameters.put("EXTERNAL", "TRUE");
                parameters.put(TABLE_TYPE_PROP, ICEBERG_TABLE_TYPE_VALUE);
                parameters.put(METADATA_LOCATION, newMetadataLocation);
                if (tableComment != null) {
                    parameters.put(TABLE_COMMENT, tableComment);
                }
                Table.Builder builder = Table.builder()
                        .setDatabaseName(database)
                        .setTableName(tableName)
                        .setOwner(owner.orElseThrow(() -> new IllegalStateException("Owner not set")))
                        .setTableType(PrestoTableType.EXTERNAL_TABLE)
                        .setDataColumns(toHiveColumns(metadata.schema().columns()))
                        .withStorage(storage -> storage.setLocation(metadata.location()))
                        .withStorage(storage -> storage.setStorageFormat(STORAGE_FORMAT))
                        .setParameters(parameters);
                table = builder.build();
            }
            else {
                Table currentTable = getTable();
                checkState(currentMetadataLocation != null, "No current metadata location for existing table");
                String metadataLocation = currentTable.getParameters().get(METADATA_LOCATION);
                if (!currentMetadataLocation.equals(metadataLocation)) {
                    throw new CommitFailedException("Metadata location [%s] is not same as table metadata location [%s] for %s", currentMetadataLocation, metadataLocation, getSchemaTableName());
                }
                table = Table.builder(currentTable)
                        .setDataColumns(toHiveColumns(metadata.schema().columns()))
                        .withStorage(storage -> storage.setLocation(metadata.location()))
                        .setParameter(METADATA_LOCATION, newMetadataLocation)
                        .setParameter(PREVIOUS_METADATA_LOCATION, currentMetadataLocation)
                        .build();
            }
        }
        catch (RuntimeException e) {
            try {
                io().deleteFile(newMetadataLocation);
            }
            catch (RuntimeException exception) {
                e.addSuppressed(exception);
            }
            throw e;
        }

        PrestoPrincipal owner = new PrestoPrincipal(USER, table.getOwner());
        PrincipalPrivileges privileges = new PrincipalPrivileges(
                ImmutableMultimap.<String, HivePrivilegeInfo>builder()
                        .put(table.getOwner(), new HivePrivilegeInfo(SELECT, true, owner, owner))
                        .put(table.getOwner(), new HivePrivilegeInfo(INSERT, true, owner, owner))
                        .put(table.getOwner(), new HivePrivilegeInfo(UPDATE, true, owner, owner))
                        .put(table.getOwner(), new HivePrivilegeInfo(DELETE, true, owner, owner))
                        .build(),
                ImmutableMultimap.of());
        if (base == null) {
            metastore.createTable(metastoreContext, table, privileges);
        }
        else {
            metastore.replaceTable(metastoreContext, database, tableName, table, privileges);
        }

        shouldRefresh = true;
    }

    @Override
    public FileIO io()
    {
        return fileIO;
    }

    @Override
    public String metadataFileLocation(String filename)
    {
        TableMetadata metadata = current();
        String location;
        if (metadata != null) {
            String writeLocation = metadata.properties().get(WRITE_METADATA_LOCATION);
            if (writeLocation != null) {
                return format("%s/%s", writeLocation, filename);
            }
            location = metadata.location();
        }
        else {
            location = this.location.orElseThrow(() -> new IllegalStateException("Location not set"));
        }
        return format("%s/%s/%s", location, METADATA_FOLDER_NAME, filename);
    }

    @Override
    public LocationProvider locationProvider()
    {
        TableMetadata metadata = current();
        return LocationProviders.locationsFor(metadata.location(), metadata.properties());
    }

    private Table getTable()
    {
        return metastore.getTable(metastoreContext, database, tableName)
                .orElseThrow(() -> new TableNotFoundException(getSchemaTableName()));
    }

    private SchemaTableName getSchemaTableName()
    {
        return new SchemaTableName(database, tableName);
    }

    private String writeNewMetadata(TableMetadata metadata, int newVersion)
    {
        String newTableMetadataFilePath = newTableMetadataFilePath(metadata, newVersion);
        OutputFile newMetadataLocation = fileIO.newOutputFile(newTableMetadataFilePath);

        // write the new metadata
        TableMetadataParser.write(metadata, newMetadataLocation);

        return newTableMetadataFilePath;
    }

    private void refreshFromMetadataLocation(String newLocation)
    {
        // use null-safe equality check because new tables have a null metadata location
        if (Objects.equals(currentMetadataLocation, newLocation)) {
            shouldRefresh = false;
            return;
        }

        AtomicReference<TableMetadata> newMetadata = new AtomicReference<>();
        Tasks.foreach(newLocation)
                .retry(20)
                .exponentialBackoff(100, 5000, 600000, 4.0)
                .suppressFailureWhenFinished()
                .run(metadataLocation -> newMetadata.set(
                        TableMetadataParser.read(this, io().newInputFile(metadataLocation))));

        if (newMetadata.get() == null) {
            throw new TableNotFoundException(getSchemaTableName(), "Table metadata is missing.");
        }

        String newUUID = newMetadata.get().uuid();
        if (currentMetadata != null) {
            checkState(newUUID == null || newUUID.equals(currentMetadata.uuid()),
                    "Table UUID does not match: current=%s != refreshed=%s", currentMetadata.uuid(), newUUID);
        }

        currentMetadata = newMetadata.get();
        currentMetadataLocation = newLocation;
        version = parseVersion(newLocation);
        shouldRefresh = false;
    }

    private static String newTableMetadataFilePath(TableMetadata meta, int newVersion)
    {
        String codec = meta.property(METADATA_COMPRESSION, METADATA_COMPRESSION_DEFAULT);
        return metadataFileLocation(meta, format("%05d-%s%s", newVersion, randomUUID(), getFileExtension(codec)));
    }

    private static String metadataFileLocation(TableMetadata metadata, String filename)
    {
        String location = metadata.properties().get(WRITE_METADATA_LOCATION);
        if (location != null) {
            return format("%s/%s", location, filename);
        }
        return format("%s/%s/%s", metadata.location(), METADATA_FOLDER_NAME, filename);
    }

    private static int parseVersion(String metadataLocation)
    {
        int versionStart = metadataLocation.lastIndexOf('/') + 1; // if '/' isn't found, this will be 0
        int versionEnd = metadataLocation.indexOf('-', versionStart);
        try {
            return parseInt(metadataLocation.substring(versionStart, versionEnd));
        }
        catch (NumberFormatException | IndexOutOfBoundsException e) {
            log.warn(e, "Unable to parse version from metadata location: %s", metadataLocation);
            return -1;
        }
    }

    private static List<Column> toHiveColumns(List<NestedField> columns)
    {
        return columns.stream()
                .map(column -> new Column(
                        column.name(),
                        HiveType.toHiveType(HiveSchemaUtil.convert(column.type())),
                        Optional.empty()))
                .collect(toImmutableList());
    }
}


text:
#include "cv.h"
#include "highgui.h"
using namespace cv;
using namespace std;
int main(int argc, char **argv) {
    std::cout << argv[1] << std::endl;
    Mat imageForShow = imread(argv[1]);
    if(imageForShow.empty())
	      return -1;
	unsigned char *data=imageForShow.ptr();

	SiftGPU  sift;

	char * argg[] ={ "-fo", "-1", "-v", "1"};//,"-d","10"
	//-fo -1,  starting from -1 octave
	//-v 1,  only print out # feature and overall time
	sift.ParseParam(4, argg);

	int support = sift.CreateContextGL();	//call VerfifyContexGL instead if using your own GL context
	//int support = sift->VerifyContextGL();

	if(support != SiftGPU::SIFTGPU_FULL_SUPPORTED)
	    return 0;
	sift.RunSIFT(imageForShow.size().width, imageForShow.size().height, data, GL_RGB, GL_UNSIGNED_BYTE);
	int num = sift.GetFeatureNum();
	cout << "sift feature counts: " << num << endl;
	sift.SaveSIFT((string(argv[1]).substr(0,string(argv[1]).length()-4)+".key").c_str());

//       //allocate memory for readback
//
//       vector<float> descriptors(128*num);
//       vector<SiftGPU::SiftKeypoint> keys(num);
//       //read back keypoints and normalized descritpros
//
//       //specify NULL if you don't need keypionts or descriptors
//
//       sift.GetFeatureVector(&keys[0], &descriptors[0]);
//       Point2f pt;
//       for(int i = 0; i < keys.size(); i ++)
//       {
// 	pt.x = (int)keys.at(i).x;
// 	pt.y = (int)keys.at(i).y;
// 	circle(imageForShow, pt, 1, CV_RGB(0, 255, 0), -1);
//       }
// 	namedWindow("result",CV_WINDOW_AUTOSIZE);
// 	imshow("result", imageForShow);
// 	imwrite("result.jpg", imageForShow);
    return 0;
}


text:
package main

import (
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"time"

	"strings"

	"github.com/golang/glog"
	"github.com/hashicorp/vault/api"
)

// AuthInterface is the authentication interface
type AuthInterface interface {
	// Create and handle renewals of the token
	Create(*vaultAuthOptions) (string, error)
}

// VaultService is the main interface into the vault API - placing into a structure
// allows one to easily mock it and two to simplify the interface for us
type VaultService struct {
	vaultURL string
	// the vault client
	client *api.Client
	// the vault config
	config *api.Config
	// the token to authenticate with
	token string
	// the listener channel - technically we only have the one listener but there a long term reasons for adding this
	listeners []chan VaultEvent
	// a channel to inform of a new resource to processor
	resourceChannel chan *watchedResource
}

// VaultEvent is the definition which captures a change
type VaultEvent struct {
	// the resource this relates to
	Resource *VaultResource
	// the secret associated
	Secret map[string]interface{}
	// type of this event (success or failure)
	Type EventType
}

type EventType int

const (
	EventTypeSuccess EventType = iota
	EventTypeFailure EventType = iota
)

// NewVaultService creates a new implementation to speak to vault and retrieve the resources
//	url			: the url of the vault service
func NewVaultService(url string) (*VaultService, error) {
	var err error

	// step: create the config for client
	service := new(VaultService)
	service.vaultURL = url
	service.listeners = make([]chan VaultEvent, 0)

	// step: create the service processor channels
	service.resourceChannel = make(chan *watchedResource, 20)

	// step: retrieve a vault client
	service.client, err = newVaultClient(&options)
	if err != nil {
		return nil, err
	}

	// step: start the service processor off
	service.vaultServiceProcessor()

	return service, nil
}

// AddListener ... add a listener to the events listeners
func (r *VaultService) AddListener(ch chan VaultEvent) {
	glog.V(10).Infof("adding the listener: %v", ch)
	r.listeners = append(r.listeners, ch)
}

// Watch adds a watch on a resource and inform, renew which required and inform us when
// the resource is ready
func (r VaultService) Watch(rn *VaultResource) {
	r.resourceChannel <- &watchedResource{resource: rn}
}

// vaultServiceProcessor is the background routine responsible for retrieving the resources, renewing when required and
// informing those who are watching the resource that something has changed
func (r *VaultService) vaultServiceProcessor() {
	go func() {
		// a list of resource being watched
		var items []*watchedResource

		// the channel to receive renewal notifications on
		renewChannel := make(chan *watchedResource, 10)
		retrieveChannel := make(chan *watchedResource, 10)
		revokeChannel := make(chan *watchedResource, 10)
		statsChannel := time.NewTicker(options.statsInterval)

		for {
			select {
			// A new resource is being added to the service processor;
			//  - schedule the resource for retrieval
			case x := <-r.resourceChannel:
				glog.V(4).Infof("adding a resource into the service processor, resource: %s", x.resource)
				// step: add to the list of resources
				items = append(items, x)
				// step: push into the retrieval channel
				r.scheduleNow(x, retrieveChannel)

			// Retrieve a resource from vault
			//  - we retrieve the resource from vault
			//  - if we error attempting to retrieve the secret, we background and reschedule an attempt to add it
			//  - if ok, we grab the lease it and lease time, we setup a notification on renewal
			case x := <-retrieveChannel:
				// step: skip this resource if it's reached maxRetries
				if x.resource.maxRetries > 0 && x.resource.retries > x.resource.maxRetries {
					glog.V(4).Infof("skipping resource as it's failed %d/%d times", x.resource.retries, x.resource.maxRetries+1)
					break
				}

				// step: save the current lease if we have one
				leaseID := ""
				if x.secret != nil && x.secret.LeaseID != "" {
					leaseID = x.secret.LeaseID
					glog.V(10).Infof("resource: %s has a previous lease: %s", x.resource, leaseID)
				}

				err := r.get(x)
				if err != nil {
					glog.Errorf("failed to retrieve the resource: %s from vault, error: %s", x.resource, err)
					// reschedule the attempt for later
					r.scheduleIn(x, retrieveChannel, getDurationWithin(3, 10))
					x.resource.retries++
					r.upstream(VaultEvent{
						Resource: x.resource,
						Type:     EventTypeFailure,
					})
					break
				}

				glog.V(4).Infof("successfully retrieved resource: %s, leaseID: %s", x.resource, x.secret.LeaseID)
				x.resource.retries = 0

				// step: if we had a previous lease and the option is to revoke, lets throw into the revoke channel
				if leaseID != "" && x.resource.revoked {
					// step: make a rough copy
					copy := &watchedResource{
						secret: &api.Secret{
							LeaseID: x.secret.LeaseID,
						},
					}

					r.scheduleIn(copy, revokeChannel, x.resource.revokeDelay)
				}

				// step: setup a timer for renewal
				x.notifyOnRenewal(renewChannel)

				// step: update the upstream consumers
				r.upstream(VaultEvent{
					Resource: x.resource,
					Secret:   x.secret.Data,
					Type:     EventTypeSuccess,
				})

			// A watched resource is coming up for renewal
			// 	- we attempt to renew the resource from vault
			//	- if we encounter an error, we reschedule the attempt for the future
			//	- if we're ok, we update the watchedResource and we send a notification of the change upstream
			case x := <-renewChannel:
				// step: skip this resource if it's reached maxRetries
				if x.resource.maxRetries > 0 && x.resource.retries > x.resource.maxRetries {
					glog.V(4).Infof("skipping resource as it's failed %d/%d times", x.resource.retries, x.resource.maxRetries+1)
					break
				}

				glog.V(4).Infof("resource: %s, lease: %s up for renewal, renewable: %t, revoked: %t", x.resource,
					x.secret.LeaseID, x.resource.renewable, x.resource.revoked)

				// step: we need to check if the lease has expired?
				if time.Now().After(x.leaseExpireTime) {
					glog.V(3).Infof("the lease on resource: %s has expired, we need to get a new lease", x.resource)
					// push into the retrieval channel and break
					r.scheduleNow(x, retrieveChannel)
					break
				}

				// step: are we renewing the resource?
				if x.resource.renewable {
					// step: is the underlining resource even renewable? - otherwise we can just grab a new lease
					if !x.secret.Renewable {
						glog.V(10).Infof("the resource: %s is not renewable, retrieving a new lease instead", x.resource)
						r.scheduleNow(x, retrieveChannel)
						break
					}

					// step: lets renew the resource
					err := r.renew(x)
					if err != nil {
						// bad request errors won't be fixed via a retry they can happen if the resource (or its lease) is revoked
						// permission errors won't be fixed via a retry they can happen if the token (or its lease) is revoked
						if strings.Contains(err.Error(), "Code: 400") ||
							strings.Contains(err.Error(), "Code: 403") {
							glog.Errorf("failed to renew the resource: %s for renewal, retrieving a new lease instead, error: %s", x.resource, err)
							r.scheduleNow(x, retrieveChannel)
							break
						}
						glog.Errorf("failed to renew the resource: %s for renewal, error: %s", x.resource, err)
						// reschedule the attempt for later
						r.scheduleIn(x, renewChannel, getDurationWithin(3, 10))
						x.resource.retries++
						r.upstream(VaultEvent{
							Resource: x.resource,
							Type:     EventTypeFailure,
						})
						break
					}

					glog.V(4).Infof("successfully renewed resource: %s, leaseID: %s", x.resource, x.secret.LeaseID)
					x.resource.retries = 0
				}

				// step: the option for this resource is not to renew the secret but regenerate a new secret
				if !x.resource.renewable {
					glog.V(4).Infof("resource: %s flagged as not renewable, shifting to regenerating the resource", x.resource)
					r.scheduleNow(x, retrieveChannel)
					break
				}

				// step: setup a timer for renewal
				x.notifyOnRenewal(renewChannel)

				// step: update any listener upstream
				r.upstream(VaultEvent{
					Resource: x.resource,
					Secret:   x.secret.Data,
					Type:     EventTypeSuccess,
				})

			// We receive a lease ID along on the channel, just revoke the lease when you can
			case x := <-revokeChannel:
				err := r.revoke(x.secret.LeaseID)
				if err != nil {
					glog.Errorf("failed to revoke the lease: %s, error: %s", x.secret.LeaseID, err)
				}

			// The statistics timer has gone off; we iterate the watched items and
			case <-statsChannel.C:
				glog.V(3).Infof("stats: %d resources being watched", len(items))
				for _, item := range items {
					glog.V(3).Infof("resourse: %s, lease id: %s, renewal in: %s seconds, expiration: %s",
						item.resource, item.secret.LeaseID, item.renewalTime, item.leaseExpireTime)
				}
			}
		}
	}()
}

// scheduleNow ... a helper method to perform an immediate reschedule into a channel
//	rn			: a pointer to the watched resource you wish to reschedule
//	ch			: the channel the resource should be placed into
func (r VaultService) scheduleNow(rn *watchedResource, ch chan *watchedResource) {
	r.scheduleIn(rn, ch, time.Duration(0))
}

// scheduleIn ... schedules an event back into a channel after n seconds
//	rn			: a referrence some reason you wish to pass
//	ch			: the channel the resource should be placed into
//	min			: the minimum amount of time i'm willing to wait
//	max			: the maximum amount of time i'm willing to wait
func (r VaultService) scheduleIn(rn *watchedResource, ch chan *watchedResource, duration time.Duration) {
	go func(x *watchedResource) {
		glog.V(3).Infof("rescheduling the resource: %s, channel: %v", rn.resource, ch)
		// step: are we doing a random wait?
		if duration > 0 {
			<-time.After(duration)
		}
		ch <- x
	}(rn)
}

// upstream ... the resource has changed thus we notify the upstream listener
//	item		: the item which has changed
func (r VaultService) upstream(item VaultEvent) {
	// step: chunk this into a go-routine not to block us
	for _, listener := range r.listeners {
		go func(ch chan VaultEvent) {
			ch <- item
		}(listener)
	}
}

// renew attempts to renew the lease on a resource
// 	rn			: the resource we wish to renew the lease on
func (r VaultService) renew(rn *watchedResource) error {
	glog.V(4).Infof("attempting to renew the lease: %s on resource: %s", rn.secret.LeaseID, rn.resource)
	// step: check the resource is renewable
	if !rn.secret.Renewable {
		return fmt.Errorf("the resource: %s is not renewable", rn.resource)
	}

	secret, err := r.client.Sys().Renew(rn.secret.LeaseID, 0)
	if err != nil {
		return err
	}

	// step: update the resource
	rn.lastUpdated = time.Now()
	leaseDuration := time.Duration(secret.LeaseDuration) * time.Second
	rn.leaseExpireTime = rn.lastUpdated.Add(leaseDuration)

	glog.V(3).Infof("renewed resource: %s, leaseId: %s, leaseDuration: %s, expiration: %s",
		rn.resource, rn.secret.LeaseID, leaseDuration, rn.leaseExpireTime)

	return nil
}

// revoke attempts to revoke the lease of a resource
//	lease		: the lease lease which was given when you got it
func (r VaultService) revoke(lease string) error {
	glog.V(3).Infof("attemping to revoking the lease: %s", lease)

	err := r.client.Sys().Revoke(lease)
	if err != nil {
		return err
	}
	glog.V(3).Infof("successfully revoked the leaseId: %s", lease)

	return nil
}

// get retrieves a secret from the vault
//	rn			: the watched resource
func (r VaultService) get(rn *watchedResource) error {
	var err error
	var secret *api.Secret
	// step: not sure who to cast map[string]string to map[string]interface{} doesn't like it anyway i try and do it

	params := make(map[string]interface{}, 0)
	for k, v := range rn.resource.options {
		params[k] = interface{}(v)
	}
	glog.V(10).Infof("resource: %s, path: %s, params: %v", rn.resource.resource, rn.resource.path, params)

	glog.V(5).Infof("attempting to retrieve the resource: %s from vault", rn.resource)
	// step: perform a request to vault
	switch rn.resource.resource {
	case "raw":
		request := r.client.NewRequest("GET", "/v1/"+rn.resource.path)
		for k, v := range rn.resource.options {
			request.Params.Add(k, v)
		}
		resp, err := r.client.RawRequest(request)
		if err != nil {
			return err
		}
		// step: read the response
		content, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			return err
		}
		// step: construct a secret from the response
		secret = &api.Secret{
			LeaseID:   "raw",
			Renewable: false,
			Data: map[string]interface{}{
				"content": fmt.Sprintf("%s", content),
			},
		}
		if rn.resource.update > 0 {
			secret.LeaseDuration = int(rn.resource.update.Seconds())
		} else {
			secret.LeaseDuration = int((time.Duration(24) * time.Hour).Seconds())
		}
	case "pki":
		secret, err = r.client.Logical().Write(fmt.Sprintf(rn.resource.path), params)
	case "transit":
		secret, err = r.client.Logical().Write(fmt.Sprintf(rn.resource.path), params)
	case "aws":
		fallthrough
	case "cubbyhole":
		fallthrough
	case "gcp":
		fallthrough
	case "mysql":
		fallthrough
	case "postgres":
		fallthrough
	case "database":
		fallthrough
	case "secret":
		secret, err = r.client.Logical().Read(rn.resource.path)
		// We must generate the secret if we have the create flag
		if rn.resource.create && secret == nil && err == nil {
			glog.V(3).Infof("Create param specified, creating resource: %s", rn.resource.path)
			params["value"] = newPassword(int(rn.resource.size))
			secret, err = r.client.Logical().Write(fmt.Sprintf(rn.resource.path), params)
			glog.V(3).Infof("Secret created: %s", rn.resource.path)
			if err == nil {
				// Populate the secret data as stored in Vault...
				secret, err = r.client.Logical().Read(rn.resource.path)
			}
		}
		// if there is a top-level metadata key this is from a v2 kv store
		if err == nil && secret != nil {
			if _, ok := secret.Data["metadata"]; ok {
				secret.Data = secret.Data["data"].(map[string]interface{})
			}
		}
	case "ssh":
		publicKeyData, err := ioutil.ReadFile(params["public_key_path"].(string))

		if err != nil {
			return fmt.Errorf("could not read data at specified public_key_path")
		}

		publicKeyDataString := string(publicKeyData)

		sshParams := map[string]interface{}{
			"public_key": publicKeyDataString,
			"cert_type":  params["cert_type"].(string),
		}

		secret, err = r.client.Logical().Write(fmt.Sprintf(rn.resource.path), sshParams)
	}
	// step: check the error if any
	if err != nil {
		if strings.Contains(err.Error(), "missing client token") {
			// decision: until the rewrite, lets just exit for now
			glog.Fatalf("the vault token is no longer valid, exitting, error: %s", err)
		}
		return err
	}
	if secret == nil && err == nil {
		return fmt.Errorf("the resource does not exist")
	}

	if secret == nil {
		return fmt.Errorf("unable to retrieve the secret")
	}

	// step: update the watched resource
	rn.lastUpdated = time.Now()
	rn.secret = secret
	leaseDuration := time.Duration(rn.secret.LeaseDuration) * time.Second
	rn.leaseExpireTime = rn.lastUpdated.Add(leaseDuration)

	glog.V(3).Infof("retrieved resource: %s, leaseId: %s, leaseDuration: %s, expiration: %s",
		rn.resource, rn.secret.LeaseID, leaseDuration, rn.leaseExpireTime)

	return err
}

// newVaultClient creates and authenticates a vault client
func newVaultClient(opts *config) (*api.Client, error) {
	var err error
	var token string

	config := api.DefaultConfig()
	config.Address = opts.vaultURL

	config.HttpClient.Transport, err = buildHTTPTransport(opts)
	if err != nil {
		return nil, err
	}

	// step: create the actual client
	client, err := api.NewClient(config)
	if err != nil {
		return nil, err
	}

	plugin := opts.vaultAuthOptions.Method
	switch plugin {
	case "userpass":
		token, err = NewUserPassPlugin(client).Create(opts.vaultAuthOptions)
	case "approle":
		token, err = NewAppRolePlugin(client).Create(opts.vaultAuthOptions)
	case "aws-ec2":
		token, err = NewAWSEC2Plugin(client).Create(opts.vaultAuthOptions)
	case "gcp-gce":
		token, err = NewGCPGCEPlugin(client).Create(opts.vaultAuthOptions)
	case "kubernetes":
		token, err = NewKubernetesPlugin(client).Create(opts.vaultAuthOptions)
	case "token":
		opts.vaultAuthOptions.FileName = options.vaultAuthFile
		opts.vaultAuthOptions.FileFormat = options.vaultAuthFileFormat
		token, err = NewUserTokenPlugin(client).Create(opts.vaultAuthOptions)
	default:
		return nil, fmt.Errorf("unsupported authentication plugin: %s", plugin)
	}
	if err != nil {
		return nil, err
	}

	// step: set the token for the client
	client.SetToken(token)

	if opts.vaultRenewToken {

		tokeninfo, err := client.Auth().Token().LookupSelf()
		if err != nil {
			return nil, fmt.Errorf("failed to lookup token info: %s", err)
		}

		tokenttl, err := tokeninfo.TokenTTL()
		if err != nil {
			return nil, fmt.Errorf("failed to lookup token ttl: %s", err)
		}
		glog.Infof("token ttl is %v", tokenttl)
		renewPeriod := tokenttl / 2
		go func() {
			for {
				if renewPeriod < 1*time.Second {
					glog.Fatalf("fatal: token renew period is <1s, aborting")
				}
				glog.Infof("scheduling token renew in %v", renewPeriod)
				<-time.After(renewPeriod)

				glog.Infof("attempting token renew")
				newtokeninfo, err := client.Auth().Token().RenewSelf(0)
				if err != nil {
					// permission errors won't be fixed via a retry they can happen if the token (or its lease) is revoked
					if strings.Contains(err.Error(), "Code: 403") {
						glog.Fatalf("fatal: failed to renew token: %v", err)
					}
					renewPeriod = renewPeriod / 2
					glog.Warningf("error: failed to renew token, retrying in %v: %v", renewPeriod, err)
					continue
				}

				tokenttl, err := newtokeninfo.TokenTTL()
				if err != nil {
					glog.Warningf("error: failed to get new token ttl, using previous value %s: %s", renewPeriod, err)
				} else {
					glog.Infof("token ttl is %v", tokenttl)
					renewPeriod = tokenttl / 2
				}
			}
		}()
	}

	return client, nil
}

// buildHTTPTransport constructs a http transport for the http client
func buildHTTPTransport(opts *config) (*http.Transport, error) {
	// step: create the vault sidekick
	transport := &http.Transport{
		Proxy: http.ProxyFromEnvironment,
		Dial: (&net.Dialer{
			Timeout:   10 * time.Second,
			KeepAlive: 10 * time.Second,
		}).Dial,
		TLSHandshakeTimeout: 10 * time.Second,
		TLSClientConfig: &tls.Config{
			InsecureSkipVerify: opts.skipTLSVerify,
		},
	}
	if opts.skipTLSVerify {
		glog.Warning("skipping TLS verification is not recommended")
	}
	// step: are we loading a CA file
	if opts.vaultCaFile != "" {
		glog.V(3).Infof("loading the ca certificate: %s", opts.vaultCaFile)
		caCert, err := ioutil.ReadFile(opts.vaultCaFile)
		if err != nil {
			return nil, fmt.Errorf("unable to read in the ca: %s, reason: %s", opts.vaultCaFile, err)
		}
		caCertPool := x509.NewCertPool()
		caCertPool.AppendCertsFromPEM(caCert)
		transport.TLSClientConfig.RootCAs = caCertPool
	}

	return transport, nil
}


text:
/**
 *  Exercise 12,13
 */
package com.ciaoshen.thinkinjava.chapter21;
import java.util.concurrent.*;

public class Exercise12 implements Runnable{
    private volatile int i=0;
    private int duration;
    public Exercise12(int duration){
        this.duration=duration;
    }
    public synchronized void f3(){
        //System.out.println(Thread.currentThread().getName()+"#f3() @ "+System.currentTimeMillis());
        i++;i++;i++;
    }
    public void run(){
        long stop=System.currentTimeMillis()+duration;
        //System.out.println("#stop @ "+stop);
        while(System.currentTimeMillis()<stop){
            //System.out.println(Thread.currentThread().getName()+"#run() @ "+System.currentTimeMillis());
            f3();
        }
        Thread.yield();
    }
    public int getValue(){return i;}

    public class Checker implements Runnable{
        public void check(){
            int value;
            synchronized(Exercise12.this){
                value=getValue();
            }
            if(value%3!=0){
                System.out.println(value);
            }
        }
        public void run(){
            while(true){
                //System.out.println(Thread.currentThread().getName()+"#check() @ "+System.currentTimeMillis());
                check();
                Thread.yield();
            }
        }
    }

    public static void main(String[] args){
        ExecutorService mainService=Executors.newCachedThreadPool();
        ExecutorService daemonService=Executors.newCachedThreadPool(new ThreadFactory(){
            public Thread newThread(Runnable r){
                Thread th=new Thread(r);
                th.setDaemon(true);
                return th;
            }
        });
        Exercise12 task=new Exercise12(10);
        Checker checker=task.new Checker();

        mainService.execute(task);
        daemonService.execute(checker);

        mainService.shutdown();
        daemonService.shutdown();
    }
}


text:
require 'spec_helper_acceptance'

describe 'elkstack class' do
  context 'default parameters' do
    # Using puppet_apply as a helper
    it 'should work idempotently with no errors' do
      pp = <<-EOS
      class { 'elkstack': }
      EOS

      # Run it twice and test for idempotency
      apply_manifest(pp, :catch_failures => true)
      apply_manifest(pp, :catch_changes  => true)
    end

    describe package('elasticsearch') do
      it { is_expected.to be_installed }
    end

    describe service('elasticsearch') do
      it { is_expected.to be_enabled }
      it { is_expected.to be_running }
    end
  end
end


text:
package com.github.java8playground;

import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * Created by bryan on 4/6/16.
 */
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(RepeatableAnnotations.class)
public @interface RepeatableAnnotation {
    String value();
}


text:
#import "MWMessageContainer.h"

@implementation MWMessageContainer

- (void)dealloc {
    message = nil;
    timeValue = nil;
    altTimeValue = nil;
    messageTimeColor = nil;
    DefaultColor = nil;
    WarningColor = nil;
    ErrorColor = nil;
	LocalColor = nil;
	RemoteColor = nil;
}

- (id)initMessageContainerWithMessage:(NSString *)msg
							   atTime:(NSNumber *)tme
							   ofType:(int)type
					   onLocalConsole:(BOOL)_localConsole {
    self = [super init];
    if(self) {
        message = msg;
        altTimeValue = tme;
        msgType = type;
        timeValue = nil;
        DefaultColor = [NSColor colorWithCalibratedRed:0.0 green:0.5
												   blue:0.0 alpha:1.0];

        WarningColor = [NSColor brownColor];
        ErrorColor = [NSColor redColor];

		LocalColor = [NSColor textColor];
        RemoteColor = [NSColor colorNamed:@"consoleRemoteTextColor" bundle:[NSBundle bundleForClass:[self class]]];

		//[self initMessageParagraphStyle];

		[self setMessageTimeColor:msgType];
		[self setMessageColor:_localConsole];
    }
    return self;
}

+ (NSMutableParagraphStyle *)sharedMessageParagraphStyle {
	static NSMutableParagraphStyle *sharedMessageParagraphStyle = nil;

	if(sharedMessageParagraphStyle == nil){
		sharedMessageParagraphStyle = [NSMutableParagraphStyle alloc];
		[sharedMessageParagraphStyle setHeadIndent:70.0];
	}

	return sharedMessageParagraphStyle;
}

- (NSAttributedString *)messageForConsole {

	NSDictionary *timeAttributes = [NSDictionary
										dictionaryWithObjectsAndKeys:
		messageTimeColor,
		NSForegroundColorAttributeName,

		[NSFont boldSystemFontOfSize:0],
		NSFontAttributeName,

		[MWMessageContainer sharedMessageParagraphStyle],
		NSParagraphStyleAttributeName,
		nil];

	NSDictionary *messageAttributes;

		messageAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
			messageColor,
			NSForegroundColorAttributeName,

			[MWMessageContainer sharedMessageParagraphStyle],
			NSParagraphStyleAttributeName,
			nil];

    namespace bpt = boost::posix_time;
    bpt::time_duration eventTime = bpt::seconds((long)([altTimeValue longLongValue] / 1000000LL));

	NSMutableAttributedString *consoleMsg =
    [[NSMutableAttributedString alloc]
     initWithString:[NSString stringWithUTF8String:(bpt::to_simple_string(eventTime).c_str())]
     attributes:timeAttributes];

	/*  NSString * consoleMsg = [NSString stringWithFormat:@"%@",
								[[NSDate dateWithTimeIntervalSince1970:
									[altTimeValue doubleValue]]
									descriptionWithCalendarFormat:@"%H:%M:%S"
														 timeZone:nil
														   locale:nil]
		];

consoleMsg = [consoleMsg stringByAppendingString:[NSString
                                        stringWithFormat:@" %@\n", message]];
*/
	NSAttributedString *appendstring =
		[ [NSAttributedString alloc]
							initWithString:
			[NSString stringWithFormat:@":  %@\n",message]

								attributes: messageAttributes];

  //[consoleMsg appendAttributedString:appendstring];
	[consoleMsg appendAttributedString:appendstring];

	/*return [[[NSAttributedString alloc] initWithString:consoleMsg
attributes:[NSDictionary
                                        dictionaryWithObject:messageColor
													  forKey:NSForegroundColorAttributeName]]
autorelease];*/

	return consoleMsg;
}

- (void)setMessageTimeColor:(int)colorType {
    switch(colorType) {
        case MW_FATAL_ERROR_MESSAGE:
            [[clang::fallthrough]];
        case MW_ERROR_MESSAGE:
            messageTimeColor = ErrorColor;
            break;
        case MW_WARNING_MESSAGE:
            messageTimeColor = WarningColor;
            break;
        default:
            messageTimeColor = DefaultColor;
            break;
    }
}

- (void)setMessageColor:(BOOL)isLocal {
	if (isLocal) {
		messageColor = LocalColor;
	} else {
		messageColor = RemoteColor;
	}
}

- (NSColor *)messageTimeColor {
    return messageTimeColor;
}

- (NSColor *)messageColor {
	return messageColor;
}

- (NSString *)message {
    return message;
}

- (NSDate *)dateTimeValue {
    if(timeValue == nil) {
        timeValue = [NSDate dateWithTimeIntervalSince1970:[altTimeValue
			doubleValue]];
    }
    return timeValue;
}

- (NSNumber *)numberTimeValue {
    return altTimeValue;
}

- (int)type {
    return msgType;
}

@end