File indexing completed on 2024-09-08 03:28:58
0001 /* 0002 SPDX-FileCopyrightText: 2008 Akarsh Simha <akarshsimha@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 /* NOTE: This file is a NON portable C file that need not be built for 0008 KStars to be built. This file is useful only to generate binary 0009 data files and ensure that they comply with KStars' format, and 0010 hence need not be cross platform. 0011 0012 This file does not use Qt or KDE libraries as it is just provided 0013 here as a tool to build and test data files for KStars 0014 0015 Hence, we shall hide this file from the watchful eyes of Krazy 0016 */ 0017 //krazy:skip 0018 0019 #ifndef BINFILE_H 0020 #define BINFILE_H 0021 0022 #include <sys/types.h> 0023 #include <string.h> 0024 #include <stdlib.h> 0025 #include <stdio.h> 0026 #include <math.h> 0027 #include "byteorder.h" 0028 0029 /* NOTE: HTM_LEVEL and other HTM-related stuff must be defined before using this header */ 0030 0031 // Bogus Define 0032 #ifndef INDEX_ENTRY_SIZE 0033 #define INDEX_ENTRY_SIZE 12 0034 #endif 0035 0036 /* 0037 * enum listing out various possible data types 0038 */ 0039 0040 enum dataType 0041 { 0042 DT_CHAR, /* Character */ 0043 DT_INT8, /* 8-bit Integer */ 0044 DT_UINT8, /* 8-bit Unsigned Integer */ 0045 DT_INT16, /* 16-bit Integer */ 0046 DT_UINT16, /* 16-bit Unsigned Integer */ 0047 DT_INT32, /* 32-bit Integer */ 0048 DT_UINT32, /* 32-bit Unsigned Integer */ 0049 DT_CHARV, /* Fixed-length array of characters */ 0050 DT_STR, /* Variable length array of characters, either terminated by nullptr or by the limit on field size */ 0051 DT_SPCL = 0052 128 /* Flag indicating that the field requires special treatment (eg: Different bits may mean different things) */ 0053 }; 0054 0055 /* 0056 * struct to store the description of a field / data element in the binary files 0057 */ 0058 0059 typedef struct dataElement 0060 { 0061 char name[10]; 0062 int8_t size; 0063 u_int8_t type; 0064 int32_t scale; 0065 } dataElement; 0066 0067 void charv2str(char *str, char *charv, int n) 0068 { 0069 int i; 0070 for (i = 0; i < n; ++i) 0071 { 0072 *str = *charv; 0073 str++; 0074 charv++; 0075 } 0076 *str = '\0'; 0077 } 0078 0079 int displayDataElementDescription(dataElement *e) 0080 { 0081 char str[11]; 0082 charv2str(str, e->name, 10); 0083 printf("\nData Field:\n"); 0084 printf(" Name: %s\n", str); 0085 printf(" Size: %d\n", e->size); 0086 printf(" Type: %d\n", e->type); 0087 printf(" Scale: %ld\n", e->scale); 0088 } 0089 0090 // NOTE: Ineffecient. Not to be used for high-productivity 0091 // applications 0092 void swapbytes(char byteswap, void *ptr, int nbytes) 0093 { 0094 char *destptr; 0095 char *i; 0096 0097 if (!byteswap) 0098 return; 0099 0100 destptr = (char *)malloc(nbytes); 0101 i = ((char *)ptr + (nbytes - 1)); 0102 while (i >= (char *)ptr) 0103 { 0104 *destptr = *i; 0105 ++destptr; 0106 --i; 0107 } 0108 0109 destptr -= nbytes; 0110 0111 memcpy(ptr, (void *)destptr, nbytes); 0112 free(destptr); 0113 } 0114 0115 u_int32_t trixel2number(char *trixel) 0116 { 0117 int index; 0118 u_int32_t id = 0; 0119 for (index = HTM_LEVEL + 1; index >= 1; --index) 0120 { 0121 id += (trixel[index] - '0') * (u_int16_t)round(pow(4, (HTM_LEVEL + 1 - index))); 0122 } 0123 id += ((trixel[0] == 'S') ? round(pow(4, HTM_LEVEL + 1)) + 1 : 0); 0124 return id; 0125 } 0126 0127 char *number2trixel(char *trixel, u_int16_t number) 0128 { 0129 int index; 0130 u_int16_t hpv = (u_int16_t)round(pow(4, HTM_LEVEL)) * 2; 0131 if (number >= hpv) 0132 { 0133 trixel[0] = 'S'; 0134 number -= hpv; 0135 } 0136 else 0137 trixel[0] = 'N'; 0138 hpv /= 2; 0139 0140 for (index = 1; index < HTM_LEVEL + 2; ++index) 0141 { 0142 trixel[index] = (number - (number % hpv)) / hpv + '0'; 0143 number = number % hpv; 0144 hpv /= 4; 0145 } 0146 0147 trixel[HTM_LEVEL + 2] = '\0'; 0148 0149 return trixel; 0150 } 0151 0152 /* 0153 * Convert a string to an int32_t with a double as an intermediate 0154 * i : A pointer to the target int32_t 0155 * str : A pointer to the string that carries the data 0156 * ndec : Number of decimal places to truncate to 0157 */ 0158 0159 int str2int32(int32_t *i, const char *str, int ndec) 0160 { 0161 double dbl; 0162 0163 if (i == nullptr) 0164 return 0; 0165 0166 dbl = atof(str); 0167 0168 *i = (int32_t)(round(dbl * pow(10, ndec))); 0169 0170 return 1; 0171 } 0172 0173 /* 0174 * Convert a string to an int16_t with a double as an intermediate 0175 * i : A pointer to the target int16_t 0176 * str : The string that carries the data 0177 * ndec : Number of decimal places to truncate to 0178 */ 0179 0180 int str2int16(int16_t *i, const char *str, int ndec) 0181 { 0182 double dbl; 0183 0184 if (i == nullptr || str == nullptr) 0185 return 0; 0186 0187 dbl = atof(str); 0188 0189 *i = (int16_t)(round(dbl * pow(10, ndec))); 0190 0191 return 1; 0192 } 0193 0194 /* 0195 * Convert a string into a character array for n characters 0196 * a : The target array 0197 * str : The string that carries the data 0198 * n : Number of characters to convert 0199 */ 0200 0201 int str2charv(char *a, const char *str, int n) 0202 { 0203 if (a == nullptr || str == nullptr) 0204 return 0; 0205 0206 int ret = 1; 0207 0208 for (int i = 0; i < n; ++i) 0209 { 0210 a[i] = ((ret < 0) ? '\0' : str[i]); 0211 if (str[i] == '\0') /* We can do this safely because we aren't storing binary data in the DB */ 0212 ret = -1; 0213 } 0214 return ret; 0215 } 0216 0217 /* 0218 * Check whether the string passed is blank 0219 * str : String to check 0220 * returns 1 if the string is blank, 0 otherwise. 0221 */ 0222 0223 int isblank(char *str) 0224 { 0225 if (str == nullptr) 0226 return 1; 0227 0228 while (*str != '\0') 0229 { 0230 if (*str != ' ' && *str != '\n' && *str != '\r' && *str != '\t') 0231 return 0; 0232 ++str; 0233 } 0234 return 1; 0235 } 0236 0237 /* 0238 * Write one data element description into a binary file header. 0239 * 0240 * f : Handle of file to write into 0241 * name : Name of the field, as a string. Max as specified in struct dataElement 0242 * size : Size (in bytes) of the field 0243 * type : Type of the field, as specified in enum dataType 0244 * scale : Scale factor used for conversion of fixed-point reals to integers. N/A to DT_CHARV, DT_STR and DT_CHAR 0245 */ 0246 0247 int writeDataElementDescription(FILE *f, char *name, int8_t size, enum dataType type, int32_t scale) 0248 { 0249 struct dataElement de; 0250 0251 if (f == nullptr || name == nullptr) 0252 return 0; 0253 0254 str2charv(de.name, name, 10); 0255 de.size = size; 0256 de.type = type; 0257 de.scale = scale; 0258 fwrite(&de, sizeof(struct dataElement), 1, f); 0259 return 1; 0260 } 0261 0262 int writeIndexEntry(FILE *hf, u_int32_t trixel_id, u_int32_t offset, u_int32_t nrec) 0263 { 0264 if (hf == nullptr) 0265 return 0; 0266 0267 fwrite(&trixel_id, 4, 1, hf); 0268 fwrite(&offset, 4, 1, hf); 0269 fwrite(&nrec, 4, 1, hf); 0270 0271 /* Put this just for safety, in case we change our mind - we should avoid screwing things up */ 0272 if (4 + 4 + 4 != INDEX_ENTRY_SIZE) 0273 { 0274 fprintf(stderr, "CODE ERROR: 4 + 4 + 4 != INDEX_ENTRY_SIZE\n"); 0275 } 0276 0277 return 1; 0278 } 0279 0280 /* 0281 * "Increments" a trixel 0282 * 0283 * str : String to hold the incremented trixel 0284 */ 0285 /* 0286 void nextTrixel(char *trixel) { 0287 0288 char *ptr = trixel + HTM_LEVEL + 1; 0289 while(ptr > trixel) { 0290 *ptr = *ptr + 1; 0291 if(*ptr != '4') 0292 break; 0293 *ptr = '0'; 0294 ptr--; 0295 } 0296 if(*ptr == 'N') 0297 *ptr = 'S'; 0298 else if(*ptr == 'S') 0299 *ptr = '0'; 0300 } 0301 0302 */ 0303 #endif