Unable to divide the latest freebase dump - compression

I've dividing the freebase dump into smaller compressed files using a ruby script, then with freebase-rdf-2014-10-26-00-00 it stopped working, ending prematurely. Today I wrote a java program that acts the same way as ruby. Are there changes to freebase dump regarding compression?
package splitfreebase;
import java.io.*;
import java.util.zip.GZIPInputStream;
/**
*
* #author ron
*/
public class SplitFreebase {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
try {
BufferedReader in = new BufferedReader(
new InputStreamReader(
new GZIPInputStream(
new FileInputStream(args[0]))));
BufferedWriter out = null;
long cnt = 0;
int file_cnt = 0;
while (in.ready()) {
if ((cnt % 10000000) == 0) {
String name = args[0].substring(0, args[0].length() - 3)
+ "_" + file_cnt + ".gz";
if (out != null) {
out.close();
}
out = new BufferedWriter(
new OutputStreamWriter(
new GZIPOutputStream(
new FileOutputStream(name))));
file_cnt++;
}
if (out != null) {
out.write(in.readLine());
out.newLine();
}
cnt++;
}
if (out != null) {
out.close();
}
in.close();
} catch (FileNotFoundException ex) {
Logger.getLogger(SplitFreebase.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(SplitFreebase.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

This works pretty well. Java failed and ruby did too in the exact same way. I divided the problem substituting gunzip STDIN and it works now.
Freebase file:
-rw-r--r-- 1 ron users 29498770878 Nov 2 18:13 freebase-rdf-2014-11-02-00-00.gz
$ gunzip -c freebase_s19.gz | ./free_sp_stdin.rb howdy_pardner
Here is the script. I'm not a ruby programmer, may not be elegant.
require 'zlib'
file_cnt = 0;
error = ""
wgz = nil
if ARGV[1] != nil
file_cnt = ARGV[1].to_i;
end
base_name = ARGV[0]
STDIN.each_with_index do |line, idx|
#puts idx.to_s+" "+line
if((idx % 100000000) == 0)
if(idx != 0)
wgz.close
end
wgz = Zlib::GzipWriter.open(base_name + file_cnt.to_s + ".gz")
puts base_name + file_cnt.to_s + ".gz"
file_cnt+=1
end
if((idx % 1000000) == 0)
print "."
end
error = line
wgz << line
end
wgz.close
puts error

Related

Unable to print out generated list with SQL Database statements [Android Studio]

I have coded some code that connects to a databse in the internal storage of the device, runs a SQL statement to filter out excercises, then iterate through the results and create a list that can be used later in the program. However, the list returns nothing when checked with Log statements. I have checked whether the SQL statements work with log statements before the iteration and it returns correct row values.
package com.example.fit_world;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.content.res.AssetManager;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.util.Log;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import com.example.fit_world.Exercise;
public class GenerateWorkout extends AppCompatActivity {
private static final String DATABASE_NAME = "Exercises.db";
private SQLiteDatabase database;
private void copyDatabaseToInternalStorage() {
InputStream inputStream = null;
OutputStream outputStream = null;
try {
// Open the database file in the assets folder
AssetManager assetManager = getAssets();
inputStream = assetManager.open(DATABASE_NAME);
if (inputStream == null) {
throw new IOException("Failed to open file: " + DATABASE_NAME);
}
// Generate a unique file name for the database in the internal storage
File outputFile = new File(getFilesDir(), "Exercises_" + System.currentTimeMillis() + ".db");
// Check if the file already exists in the internal storage
if (outputFile.exists()) {
// Delete the file if it already exists
outputFile.delete();
}
outputStream = new FileOutputStream(outputFile);
// Copy the database file from the assets folder to the internal storage
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// Close the streams
try {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_generate_workout);
String equipmentType = "None";
String difficultyType = "Easy";
String weightGoalType = "Weight Loss";
List<Exercise> exercises = getExercisesFromDatabase(equipmentType, difficultyType, weightGoalType);
for (Exercise exercise : exercises) {
Log.d("LOL", exercise.toString());
}
}
private List<Exercise> getExercisesFromDatabase(String equipmentType, String difficultyType, String weightGoalType) {
List<Exercise> exercises = new ArrayList<>();
// Check if the database file exists in the internal storage
File databaseFile = new File(getFilesDir(), DATABASE_NAME);
if (!databaseFile.exists()) {
// If the database file does not exist, copy it from the assets folder
copyDatabaseToInternalStorage();
}
// Open the database file in the internal storage
SQLiteDatabase database = null;
Cursor cursor = null;
try {
// Open the database file in the internal storage
database = openOrCreateDatabase("Exercises.db", MODE_PRIVATE, null);
// Execute the query to retrieve the list of exercises
String query = "SELECT * FROM Exercises WHERE Equipment = ? AND Difficulty = ? AND Goal = ?";
String[] selectionArgs = new String[]{equipmentType, difficultyType, weightGoalType};
cursor = database.rawQuery(query, selectionArgs);
int rowCount = cursor.getCount();
System.out.print(rowCount);
Log.d("TAG", "Row count: " + rowCount);
Log.d("MMM", "Row count: " + database.rawQuery("SELECT * FROM exercises", null).getCount());
// Iterate through the result set and create a list of exercises
while (cursor.moveToNext()) {
int idColumnIndex = cursor.getColumnIndex("id");
int nameColumnIndex = cursor.getColumnIndex("name");
int descriptionColumnIndex = cursor.getColumnIndex("description");
int equipmentColumnIndex = cursor.getColumnIndex("equipment");
int difficultyColumnIndex = cursor.getColumnIndex("difficulty");
int weightGoalColumnIndex = cursor.getColumnIndex("weight_goal");
int requiredEquipmentColumnIndex = cursor.getColumnIndex("required_equipment");
int numberOfRepsColumnIndex = cursor.getColumnIndex("number_of_reps");
if (idColumnIndex != -1 && nameColumnIndex != -1 && descriptionColumnIndex != -1 && equipmentColumnIndex != -1 &&
difficultyColumnIndex != -1 && weightGoalColumnIndex != -1 && requiredEquipmentColumnIndex != -1 &&
numberOfRepsColumnIndex != -1) {
int id = cursor.getInt(idColumnIndex);
String name = cursor.getString(nameColumnIndex);
String description = cursor.getString(descriptionColumnIndex);
String equipment = cursor.getString(equipmentColumnIndex);
String difficulty = cursor.getString(difficultyColumnIndex);
String weightGoal = cursor.getString(weightGoalColumnIndex);
String requiredEquipment = cursor.getString(requiredEquipmentColumnIndex);
int numberOfReps = cursor.getInt(numberOfRepsColumnIndex);
Exercise exercise = new Exercise(id, name, description, equipment, difficulty, weightGoal, requiredEquipment, numberOfReps);
exercises.add(exercise);
Log.d("TAG", "Exercise name: " + name);
Log.d("TAG", "Exercise description: " + description);
Log.d("TAG", "Exercise equipment: " + equipment);
Log.d("TAG", "Number of exercises retrieved: " + exercises.size());
}
}
} catch (SQLException e) {
e.printStackTrace();
Log.e("TAG", "Error accessing database: " + e.getMessage());
} finally {
// Close the cursor and database
if (cursor != null) {
cursor.close();
}
if (database != null) {
database.close();
}
}
return exercises;
}
}
I tried to use log statements in order to see the list of excercises that is printed however nothing gets printed to the logcat, the SQL statements work as I have used a log statement to see the values printed and that works fine
I suspect that when valid data exists that something does get printed out, but not what is expected and therefore perhaps missed.
More specifically what is printed depends upon the toString method of the Exercise class as is used by:-
for (Exercise exercise : exercises) {
Log.d("LOL", exercise.toString());
}
It may be something along the lines of D/LOL: a.a.so75035530javasqliteemptylist.Exercise#58c3a3e (this from an adaption of the code you have supplied)
Otherwise the core code appears to be fine. The following was the adaptated code used to test with some data (a single row) in the database that is opened (just one row):-
private List<Exercise> getExercisesFromDatabase(String equipmentType, String difficultyType, String weightGoalType) {
List<Exercise> exercises = new ArrayList<>();
// Check if the database file exists in the internal storage
/*
File databaseFile = new File(getFilesDir(), DATABASE_NAME);
if (!databaseFile.exists()) {
// If the database file does not exist, copy it from the assets folder
copyDatabaseToInternalStorage();
}
*/
// Open the database file in the internal storage
SQLiteDatabase database = null;
Cursor cursor = null;
try {
// Open the database file in the internal storage
//database = openOrCreateDatabase("Exercises.db", MODE_PRIVATE, null);
File dbfile = this.getDatabasePath(DATABASE_NAME);
database = SQLiteDatabase.openOrCreateDatabase(dbfile,null);
// Execute the query to retrieve the list of exercises
String query = "SELECT * FROM Exercises /*WHERE Equipment = ? AND Difficulty = ? AND weightGoal = ?*/";
String[] selectionArgs = new String[]{equipmentType, difficultyType, weightGoalType};
cursor = database.rawQuery(query, /*selectionArgs*/ new String[]{});
DatabaseUtils.dumpCursor(cursor);
int rowCount = cursor.getCount();
System.out.print(rowCount);
Log.d("TAG", "Row count: " + rowCount);
Log.d("MMM", "Row count: " + database.rawQuery("SELECT * FROM exercises", null).getCount());
// Iterate through the result set and create a list of exercises
while (cursor.moveToNext()) {
int idColumnIndex = cursor.getColumnIndex("id");
int nameColumnIndex = cursor.getColumnIndex("name");
int descriptionColumnIndex = cursor.getColumnIndex("description");
int equipmentColumnIndex = cursor.getColumnIndex("equipment");
int difficultyColumnIndex = cursor.getColumnIndex("difficulty");
int weightGoalColumnIndex = cursor.getColumnIndex("weightGoal");
int requiredEquipmentColumnIndex = cursor.getColumnIndex("requiredEquipment");
int numberOfRepsColumnIndex = cursor.getColumnIndex("numberOfReps");
if (1 == 1 /*idColumnIndex != -1 && nameColumnIndex != -1 && descriptionColumnIndex != -1 && equipmentColumnIndex != -1 &&
difficultyColumnIndex != -1 && weightGoalColumnIndex != -1 && requiredEquipmentColumnIndex != -1 &&
numberOfRepsColumnIndex != -1*/) {
int id = cursor.getInt(idColumnIndex);
String name = cursor.getString(nameColumnIndex);
String description = cursor.getString(descriptionColumnIndex);
String equipment = cursor.getString(equipmentColumnIndex);
String difficulty = cursor.getString(difficultyColumnIndex);
String weightGoal = cursor.getString(weightGoalColumnIndex);
String requiredEquipment = cursor.getString(requiredEquipmentColumnIndex);
int numberOfReps = cursor.getInt(numberOfRepsColumnIndex);
Exercise exercise = new Exercise(id, name, description, equipment, difficulty, weightGoal, requiredEquipment, numberOfReps);
exercises.add(exercise);
Log.d("TAG", "Exercise name: " + name);
Log.d("TAG", "Exercise description: " + description);
Log.d("TAG", "Exercise equipment: " + equipment);
Log.d("TAG", "Number of exercises retrieved: " + exercises.size());
}
}
} catch (SQLException e) {
e.printStackTrace();
Log.e("TAG", "Error accessing database: " + e.getMessage());
} finally {
// Close the cursor and database
if (cursor != null) {
cursor.close();
}
if (database != null) {
database.close();
}
}
return exercises;
}
As can be seen rather than test using an asset etc, the database is in the standard location, it being created and populated in the initial (MainActivity) which is
:-
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(this,GenerateWorkout.class);
frigDatabase();
startActivity(intent);
}
void frigDatabase() {
SQLiteDatabase db;
String dbname = GenerateWorkout.DATABASE_NAME;
File dbfile = this.getDatabasePath(dbname);
boolean exists = dbfile.exists();
db = SQLiteDatabase.openOrCreateDatabase(dbfile,null);
if (!exists) {
db.execSQL("CREATE TABLE exercises (" +
"id INTEGER PRIMARY KEY," +
"name TEXT," +
"description TEXT," +
"equipment TEXT," +
"difficulty TEXT," +
"weightGoal TEXT," +
"requiredEquipment TEXT," +
"numberOfReps INTEGER DEFAULT 10" +
");"
);
ContentValues cv = new ContentValues();
cv.put("name","fred");
cv.put("description","d1");
cv.put("equipment","E1");
cv.put("difficulty","hard");
cv.put("weightGoal","10kg");
cv.put("requiredEquipment","ALL");
db.insert("exercises",null,cv);
}
}
}
other changes made were to select the one and only row (and to use column names based upon the Exercise class (note that getColumnIndex is case dependent)).
you may also notice the use of the DatabaseUtils dumpCursor method with this then the resultant output used to test was
:-
2023-01-07 09:34:55.792 I/System.out: >>>>> Dumping cursor android.database.sqlite.SQLiteCursor#67e09f
2023-01-07 09:34:55.792 I/System.out: 0 {
2023-01-07 09:34:55.793 I/System.out: id=1
2023-01-07 09:34:55.793 I/System.out: name=fred
2023-01-07 09:34:55.793 I/System.out: description=d1
2023-01-07 09:34:55.793 I/System.out: equipment=E1
2023-01-07 09:34:55.793 I/System.out: difficulty=hard
2023-01-07 09:34:55.793 I/System.out: weightGoal=10kg
2023-01-07 09:34:55.793 I/System.out: requiredEquipment=ALL
2023-01-07 09:34:55.793 I/System.out: numberOfReps=10
2023-01-07 09:34:55.793 I/System.out: }
2023-01-07 09:34:55.793 I/System.out: <<<<<
2023-01-07 09:34:55.793 D/TAG: Row count: 1
2023-01-07 09:34:55.794 D/MMM: Row count: 1
2023-01-07 09:34:55.795 D/TAG: Exercise name: fred
2023-01-07 09:34:55.795 D/TAG: Exercise description: d1
2023-01-07 09:34:55.795 D/TAG: Exercise equipment: E1
2023-01-07 09:34:55.795 D/TAG: Number of exercises retrieved: 1
2023-01-07 09:34:55.802 D/LOL: a.a.so75035530javasqliteemptylist.Exercise#ca545ec
As you can see the output/results are consistent with the expectation BUT the very last line is what is obtained from the loop through the returned List and thus probably not what was expected.
However if the following were used:-
List<Exercise> exercises = getExercisesFromDatabase(equipmentType, difficultyType, weightGoalType);
for (Exercise exercise : exercises) {
Log.d("LOL", exercise.toString());
Log.d("LOL_","Name is " + exercise.name + " Description is " + exercise.description + " etc."); /*<<<<<<<<<< ADDED >>>>>>>>>>*/
}
Then the output is would be more recognisable:-
2023-01-07 09:51:07.442 D/LOL: a.a.so75035530javasqliteemptylist.Exercise#ca545ec
2023-01-07 09:51:07.442 D/LOL_: Name is fred Description is d1 etc.
Additional
As you say that the dumpCursor does extract the expected data. Then the most likely issue is that at least one of the ??columnIndex index values is looking for a column that is not in the cursor and is hence -1 and thus will not satisfy the if statement (if (idColumnIndex != -1 && nameColumnIndex != ....) (check the dumpCursor output is tells you the actual column names)
Adding a breakpoint on the first attempt to get a value from the cursor in the body of the if (note that the IF clause has been changed to always be true to allow debug to enter the body) and running in debug mode. This would allow you to see what is what. The following is an example that shows the breakpoint (red dot placed by clicking the line number) and the result of running the App in debug mode (Shift F9) :-
As can be ascertained weightGaolIndex is -1 and thus that the column name, as per the line int weightGoalColumnIndex = cursor.getColumnIndex("Goal"); (note Goal purposefully used to produce the -1(. Using debug to expand cursor and then to expand mColumnNameMap shows:-
i.e. the column name in the Cursor is weigthGoal NOT Goal
You should also note that the getColumnIndex method is case sensitive so the case of the name being searched MUST match the case of the column in the cursor.

Bukkit Player check achievements

I don't know what I should put into player.getAdvancementProgress(Here).
if (player.getAdvancementProgress().isDone()) {
}
Maybe someone knows something?
You should use an Advancement object, specially the advancement that you are looking for informations.
You can get it with Bukkit.getAdvancement(NamespacedKey.fromString("advancement/name")) where advancement/name can be nether/all_potions for example. You can get all here (column: "Resource location). If you are getting it from command, I suggest you to add tab complete.
Example of TAB that show only not-done success :
#Override
public List<String> onTabComplete(CommandSender sender, Command cmd, String label, String[] arg) {
List<String> list = new ArrayList<>();
if(!(sender instanceof Player))
return list;
Player p = (Player) sender;
String prefix = arg[arg.length - 1].toLowerCase(Locale.ROOT); // the begin of the searched advancement
Bukkit.advancementIterator().forEachRemaining((a) -> {
AdvancementProgress ap = p.getAdvancementProgress(a);
if((prefix.isEmpty() || a.getKey().getKey().toLowerCase().startsWith(prefix)) && !ap.isDone() && !a.getKey().getKey().startsWith("recipes"))
list.add(a.getKey().getKey());
});
return list;
}
Then, in the command you can do like that:
#Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] arg) {
if(!(sender instanceof Player)) // not allowed for no-player
return false;
Player p = (Player) sender;
// firstly: try to get advancement
Advancement a = Bukkit.getAdvancement(NamespacedKey.fromString(arg[0]));
if(a == null)
a = Bukkit.getAdvancement(NamespacedKey.minecraft(arg[0]));
if(a == null) // can't find it
p.sendMessage(ChatColor.RED + "Failed to find success " + arg[0]);
else { // founded :
AdvancementProgress ap = p.getAdvancementProgress(a);
p.sendMessage(ChatColor.GREEN + "Achivement " + a.getKey().getKey() + " stay: " + ChatColor.YELLOW + String.join(", ", ap.getRemainingCriteria().stream().map(this::getCleaned).collect(Collectors.toList())));
}
return false;
}
private String getCleaned(String s) { // this method is only to make content easier to read
String[] args = s.split("/");
return args[args.length - 1].replace(".png", "").replace(".jpg", "").replace("minecraft:", "").replace("_", " ");
}
Else, if you want to get all advancements, you should use Bukkit.advancementIterator().

ESP32 restarts when trying to write to NVS

I am trying to make a save system for my ESP32 project, and I have the following code:
void write_string_nvs(char *memorySlot, String key, String value)
{
nvs_handle my_handle;
esp_err_t err = nvs_open(memorySlot, NVS_READWRITE, &my_handle);
if (err == ESP_OK)
{
int kL = key.length();
int vL = value.length();
char keyA[kL + 1];
key.toCharArray(keyA, kL + 1);
char valueA[vL + 1];
value.toCharArray(valueA, vL + 1);
Serial.println("Storing \"" + String(keyA) + "\"(" + String(kL) + ")>\"" + String(valueA) + "\"(" + String(vL) + ") in NVS.");
esp_err_t err = nvs_set_blob(my_handle, keyA, &valueA, vL);
if (err == ESP_OK)
{
err = nvs_commit(my_handle);
if (err == ESP_OK)
Serial.println("Correctly saved \"" + key + "\" in " + String(memorySlot));
else
Serial.println("write_string_nvs::commit -> Could not save \"" + key + "\" in " + String(memorySlot) + ": " + esp_err_toString(err, true));
}
else
Serial.println("write_string_nvs::nvs_set_blob -> Could not save \"" + key + "\" in " + String(memorySlot) + ": " + esp_err_toString(err, true) + "");
nvs_close(my_handle);
}
else
Serial.println("Could not initialize " + String(memorySlot) + " NVS slot: " + esp_err_toString(err, true) + "");
}
I call it the following way, from a serial command:
...
String params[3];
split(serialRead, ' ', params);
String s = params[0];
String k = params[1];
String v = params[2];
bool error = false;
if (s.length() <= 0) {
error = true;
Serial.println("Please, specify an storage name");
}
if (k.length() <= 0) {
error = true;
Serial.println("Please, specify a key");
}
if (v.length() <= 0) {
error = true;
Serial.println("Please, specify a value");
}
if (!error) {
String slotName = "";
if (startsWithIgnoreCase(s, "main")) {
slotName = "storage";
}
if (startsWithIgnoreCase(s, "wifi")) {
slotName = "wifi";
}
if (slotName.length() > 1) {
Serial.println("Writing \"" + v + "\"" + " at \"\"" + k + "\" in " + slotName);
char slot[slotName.length()];
slotName.toCharArray(slot, slotName.length());
write_string_nvs(slot, k, v);
} else
Serial.println("Specified invalid slot");
}
By doing this I am trying to make a command parser to store values and read them afterwards, with the following commands: storage write <wifi/main> <key> <value> and storage read <wifi/main> <key>.
But the problem comes when I try to type the write command, and the code executes, the ESP32 Serial returns:
assertion "heap != NULL && "realloc() pointer is outside heap areas"" failed: file "/Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/heap/heap_caps.c", line 285, function: heap_caps_realloc
abort() was called at PC 0x40152903 on core 1
Backtrace: 0x40091ca4:0x3ffce0c0 0x40091ed5:0x3ffce0e0 0x40152903:0x3ffce100 0x400847a9:0x3ffce130 0x4008483d:0x3ffce150 0x4008b2e9:0x3ffce170 0x4000bedd:0x3ffce190 0x400dd4e2:0x3ffce1b0 0x400dd544:0x3ffce1d0 0x400dd6a6:0x3ffce1f0 0x400dd6d1:0x3ffce210 0x400d1b06:0x3ffce240 0x400d5939:0x3ffce260 0x400de489:0x3ffce7d0 0x40094135:0x3ffce7f0
Rebooting...
I don't know what to do, I have tried some different write and read codes, but I can't find any that stores the values correctly. The read command works, but obviously, it doesn't return anything, because the memory is empty. Here's the read command, in case you want to take a look at it:
String read_string_nvs(char *memorySlot, String key)
{
nvs_handle my_handle;
esp_err_t err = nvs_open(memorySlot, NVS_READWRITE, &my_handle);
String espErrStr = esp_err_toString(err, true);
char *value;
if (err == ESP_OK || startsWithIgnoreCase(espErrStr, "ESP_OK"))
{
size_t string_size;
int kL = key.length();
char wifi_slot[kL + 1];
key.toCharArray(wifi_slot, kL + 1);
esp_err_t err = nvs_get_str(my_handle, wifi_slot, NULL, &string_size);
value = (char *)malloc(string_size);
err = nvs_get_str(my_handle, wifi_slot, value, &string_size);
nvs_close(my_handle);
return String(value);
}
else
Serial.println("Could not open memory (\"" + espErrStr + "\")");
return espErrStr;
}
I've been with this issue for some weeks, and I really don't know what to do, maybe the system is not good for what I want, or I may be doing something wrong.
For developing I am using VSCode with PlatformIO.
Please, take a look and it and if you could tell me what's wrong or what to do, I'd be really pleased.
Thanks in advance.
I am busy with the same problem (I am going to use 4Mb of the flash as a nvs partition) and I have found a some clue: https://www.esp32.com/viewtopic.php?t=6815
It seems that problem is with the RAM-size - the system needs a RAM to create the nvs-pages-map and if it's not enough for this task - it calls the system abort.
P.S. I have decoded my firmware.elf into firmware.lst with the addresses and the assembler code and the backtrace is so:
app_main -> initArduino -> nvs_flash_init -> nvs_flash_init_partition -> nvs_flash_init_custom -> ZN3nvs_storage_init_Ejj ->ZN3nvs_Storage_populateBlobIndicesIntrusiveList -> _Znwj -> _cxa_allocate_exception -> terminatev -> cxabiv111_terminateEPFvvE - here the system aborts
To decode the .elf into .lst - just copy the firmware.elf into the folder with the xtensa-esp32-elf-objdump.exe (it is probably here .platformio\packages\toolchain-xtensa32\bin) and run in the command prompt - xtensa-esp32-elf-objdump.exe -S -l -d firmware.elf > [YourFileName].lst
These lines are problematic:
char slot[slotName.length()];
slotName.toCharArray(slot, slotName.length());
write_string_nvs(slot, k, v);
slotName.length() will return the number of characters in slotName. slot is a C string, which needs a null terminating character at the end (\0), so it needs to be declared with one byte more than the number of characters in the string. The declaration you have is too short.
You can side-step the problem by rewriting these lines as:
write_string_nvs(slotName.c_str(), k, v);
String already stores its contents as a C string internally, so the c_str() method just gives you a pointer to the buffer it manages. Be careful with this, that pointer won't be valid after the String object becomes invalid, so if the String is a variable in a function or code block, its c_str() will stop being valid when that you leave that function or code block.
Since this is some kind of heap or memory allocation issue it's possible the bug is outside of the code you shared. I would review all the code looking for instances of where you convert a String to a C character array and try using the c_str() idiom instead.
This is a pretty common problem that bites a lot of programmers.
It's also possible the problem is in your write_string_nvs() implementation.

Sitecore.Analytics.Tracker.Current is null when invoked through a pipeline

I need to redirect based on the country location the user is trying to access. For example when user trying to access http://www.example.com/ from china my site should as http://www.example.com/zh. I am checking using the sitecore tracker in pipeline process to get the country code using the below method.
public void Process(HttpRequestArgs args)
{
Assert.ArgumentNotNull(args, "args");
if (HttpContext.Current == null
|| Context.Site == null
////TODO: || Sitecore.Context.PageMode...
|| Context.Database == null || Context.Site.Name == "shell" || !this._sites.Contains(Context.Site.Name))
{
return;
}
// contains path including language and query string
// (not anchor name), but not hostname.
// We can use this to add the language back into the path.
string rawPath = Sitecore.Context.RawUrl;
if (!rawPath.StartsWith("/sitecore") && !rawPath.StartsWith("/" + Sitecore.Context.Language.Name + "/") && !rawPath.StartsWith("/" + Sitecore.Context.Language.Name) && !rawPath.StartsWith("/default.aspx"))
{
string langCode = "";
if(!string.IsNullOrEmpty(GeoIPUtils.GetUserGeoIP()))
{
try
{
string country = GeoIPUtils.GetUserGeoIP();;
if (country.Trim().ToUpper() == "China".ToUpper())
langCode = "zh";
else if (country.Trim().ToUpper() == "Japan".ToUpper())
langCode = "jp";
else if (country.Trim().ToUpper() == "Thailand".ToUpper())
langCode = "th";
else
langCode = "en";
}
catch(Exception)
{
langCode = "en";
}
}
else
{
langCode = HttpContext.Current.Request.Cookies["avc#lang"].Value.ToString();
}
if (!string.IsNullOrEmpty(langCode))
{
Language language = null;
if (Language.TryParse(langCode, out language))
{
//then try to get the language item id from the language or two letter iso code
ID langID = LanguageManager.GetLanguageItemId(language, Sitecore.Context.Database);
if (!ID.IsNullOrEmpty(langID))
{
//sometimes the language found is slightly different than official language item used in SC
language = LanguageManager.GetLanguage(language.CultureInfo.TwoLetterISOLanguageName);
if (Context.Item != null)
{
List<string> availableLangs = LanguagesWithContent(Context.Item);
if (availableLangs != null && availableLangs.Count > 0 && !availableLangs.Contains(language.CultureInfo.TwoLetterISOLanguageName.ToString()))
{
langCode = availableLangs.FirstOrDefault().ToString();
}
}
else
{
langCode = "en";
}
}
else
{
langCode = "en";
}
}
}
HttpContext.Current.Response.RedirectPermanent("/" + (String.IsNullOrEmpty(langCode) ? Sitecore.Context.Language.Name : langCode) + rawPath);
}
}
Below is the GetUserGeoIP function
public static string GetUserGeoIP()
{
string countryCode = "";
try
{
countryCode = Sitecore.Analytics.Tracker.Current.Interaction.GeoData.Country;
}
catch(Exception ex)
{
Log.Error("GetUserGeoIP Error: " + ex.Message + " Source: " + ex.Source + " Stack Trace :" + ex.StackTrace + " Inner Ex : " + ex.InnerException, ex);
countryCode = "GB";
}
if (!string.IsNullOrEmpty(countryCode))
{
var countryItem = ISO3166.FromAlpha2(countryCode);
if (countryItem != null)
return countryItem.Name;
}
return "Other";
}
But I am getting an below exception
7904 10:43:25 ERROR Cannot create tracker.
Exception: System.InvalidOperationException
Message: session is not initialized
Source: Sitecore.Analytics
at Sitecore.Analytics.Data.HttpSessionContextManager.GetSession()
at Sitecore.Analytics.Pipelines.EnsureSessionContext.EnsureContext.Process(InitializeTrackerArgs args)
at (Object , Object[] )
at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args)
at Sitecore.Analytics.DefaultTracker.EnsureSessionContext()
at Sitecore.Analytics.Pipelines.CreateTracker.GetTracker.Process(CreateTrackerArgs args)
at (Object , Object[] )
at Sitecore.Pipelines.CorePipeline.Run(PipelineArgs args)
at Sitecore.Analytics.Tracker.Initialize()
Note: The same GetUserGeoIP method is used in API which gets the correct countryName. I am using Sitecore.NET 8.0 (rev. 151127) version
Any help on this highly appreciated
Your processor is probably too soon in the pipeline(s). You can find an overview of the request pipelines here: http://sitecoreskills.blogspot.be/2015/02/a-sitecore-8-request-from-beginning-to.html
You should put your processor after the tracker has been initialized and the geo data has been fetched. I did something similar a while ago and placed my processor in the startAnalytics pipeline.
Fetching the geo data is async so that might (will) give issues when doing this in the first request pipeline. Read this article to tackle that issue by calling UpdateGeoIpData with a timespan.

Detect USB devices event

I made a console application which detects plugin and plugout events for all type of usb devices. but I wanted some filteration in it like I wanted to detect only webcams . This was done by using GUID class. The class for webcam is 'Image' class with GUID "{6bdd1fc5-810f-11d0-bec7-08002be2092f}" .The problem is that this 'Image' class is also used for scanners and I dont want to detect scanners.The code is given below:
static void Main(string[] args)
{
WqlEventQuery weqQuery = new WqlEventQuery();
weqQuery.EventClassName = "__InstanceOperationEvent";
weqQuery.WithinInterval = new TimeSpan(0, 0, 3);
weqQuery.Condition = #"TargetInstance ISA 'Win32_PnPEntity'";
ManagementEventWatcher m_mewWatcher = new ManagementEventWatcher(weqQuery);
m_mewWatcher.EventArrived += new EventArrivedEventHandler(m_mewWatcher_EventArrived);
m_mewWatcher.Start();
Console.ReadLine();
}
static void m_mewWatcher_EventArrived(object sender, EventArrivedEventArgs e)
{
bool bUSBEvent = false;
string deviceCaption = "";
string deviceType = "";
foreach (PropertyData pdData in e.NewEvent.Properties)
{
try
{
ManagementBaseObject mbo = (ManagementBaseObject)pdData.Value;
if (mbo != null)
{
foreach (PropertyData pdDataSub in mbo.Properties)
{
Console.WriteLine(pdDataSub.Name + " = " + pdDataSub.Value);
if (pdDataSub.Name == "Caption")
{
deviceCaption = pdDataSub.Value.ToString();
}
if (pdDataSub.Name == "ClassGuid" && pdDataSub.Value.ToString() == "{6bdd1fc5-810f-11d0-bec7-08002be2092f}")
{
bUSBEvent = true;
deviceType = "Image";
}
}
if (bUSBEvent)
{
if (e.NewEvent.ClassPath.ClassName == "__InstanceCreationEvent")
{
Console.WriteLine("A " + deviceType + " device " + deviceCaption + " was plugged in at " + DateTime.Now.ToString());
}
else if (e.NewEvent.ClassPath.ClassName == "__InstanceDeletionEvent")
{
Console.WriteLine("A " + deviceType + " device " + deviceCaption + " was plugged out at " + DateTime.Now.ToString());
}
}
}
}
catch (Exception ex)
{
}
}
}
for references check this link
I waited but no body answered this question so, after seeing all properties of ManagementBaseObject I found that there is a property named Service which is different for scanners. In scanners the value of Service property is usbscan while in cameras it is usbvideo.
eg.
you can do something like this
if (mbo.Properties["Service"].Value.ToString() == "usbscan")
{
//then it means it is a scanner
}
else
{
//then it means it is a camera
}
note: The main question was that how can we differentiate between a scanner and a webcam because they both use same GUID.